1.为什么需要多线程?
- 编写的代码从前往后顺序执行--执行效率低,所有代码相互等待执行
- 解决办法:把队列中无联系的分开,排成多队一起执行--多线程机制
2.并行和并发的概念
- 并行:指两个或多个事件在同一时刻一起运行【同步】
- 并发:指两个或多个事情在同一时间段内交替运行【不同步,类似于顺序执行,但是执行效率高于顺序执行】
- 顺序执行:前者全部执行完毕,后者才开始执行,往后以此类推
3.线程和进程的概念
- 进程:计算机系统中一个独立应用程序--该程序就是一个进程【之前】
- 优化了程序执行,一个程序可能包含多个进程【当前】
- 计算对于每一个进程分配相应资源【CPU+内存】
- 线程:负责进程的执行过程,是进程的一个执行单元,一个线程至少包含一个主线程(基本线程)
- 多个线程共享单个进程资源
4.如何进行线程调度和资源分配
- 进程获取操作系统分配资源--一个进程一份
- 一个进程中可以有多个线程--多个线程共享进程资源
- 进程就会把资源使用时间线上切割成时间片
- 线程获取时间片的方式(线程调度的方式)--平均分配调度,抢夺调度
- 平均分配调度:按照线程个数,平均分配资源使用时间
- 抢夺调度:给每一个线程设置优先级,优先级高的具有获取资源的概率相对更高,优先级一样则随机分配给对应的线程
- 大部分都是使用抢夺方式:操作系统,java程序
5.Java提供的API
- Java中提供了一个类表示线程:Thread
- java.lang包
- 线程:程序中可执行的线程,Java程序中允许并发运行多个线程
- 创建一个线程:编写一个类,继承Thread类,重写Thread的run方法--run方法下就是线程执行业务资源
- 使用:创建线程对象,使用线程对象调用start()启动线程
- 提供了一个接口创建线程:Runnable(它并不是线程)
- 实现了runnable,不能说明当前资源是一个线程,他是遵循线程协议,表示当前资源可以被线程加载,作为线程实现的功能使用
- 创建线程的方式:创建一个类,实现runnable接口,重写run方法
- 备注:
- Java中本身就存在至少两个线程:main主线程+垃圾回收线程
- 线程启动:是线程对象调用start方法,不是run方法,run方法是线程自己调用
6.关于线程的探索
-
1)start方法和run方法
- run方法:属于Runnable接口,Thread类重写了run方法--线程自动调用执行run方法
- start方法:用于线程启动,Thread线程类才拥有,使用数组将每个创建的线程进行存储
-
2)继承Thread和实现Runnable接口
- 继承Thread——
- 优势:继承Thread直接将业务功能类编程线程,直接进行线程相关操作
- 劣势:一旦发生继承将不能再进行扩展去继承其他类,继承发生后就只有一个线程类,不太方便用作其他功能
- 实现Runnable【推荐】——
- 优势:
- ①发生实现关系,线程资源和线程执行分开,资源类可以作出线程以外的其他事情
- ②发生实现,强制重写run方法,对使用者有很强的提示性
- ③发生实现,可以继承其他类,扩展功能
- ④可以多个线程共用一个资源对象
- 劣势:需要创建线程Thread对象进行加入线程使用
- 优势:
- 继承Thread——
-
3)Runnable接口和Thread类的扩展
- Runnable:提供了一个run方法,用于被线程调用,是线程调用资源的协定
- Thread:属性常量(最大优先级【10】,最小优先级【1】,默认优先级【5】),构造方法,方法
-
4)线程同步/线程安全
-
给资源代码块上锁,只有上一个线程使用完毕之后,下一个线程才能使用
-
三种方法:
- 1.同步块
-
- sychronsized(钥匙对象){ - 同步资源 - } -
钥匙对象:要求一定是多个线程公用一个对象【多个线程中间只存在一个】
- 2.同步方法
- 权限修饰符 sychronsized 返回值类型 方法名(参数){ - 线程执行资源 - }-
钥匙对象:this 当前类的对象 【多个线程同时拥有一个】
- 3.Lock对象:上锁
- 创建对象
- //获取lock对象
- Lock lock=new ReentrantLock();
- 多个线程同时执行的共享业务开始添加
- lock对象.lock(); //业务执行之前,上锁
- lock对象.unlock(); //业务执行完,解锁
- 3.Lock对象:上锁
-
线程同步:同步块中的资源尽量少,需要精确到代码行,块中的代码一定是影响数据安全的
-
5)线程通信 线程之间可以建立联系,相互通信关联