多线程
优化1: 多线程处理可并行的计算操作
如果有一个任务需要统计并行计算结果可以使用线程的join方法,实现在主线程中调用多个子线程的join()方法实现阻塞等待,等多个子线程都执行完毕退出时,主线程得以唤醒继续进行主要逻辑.
Thread类源码分析
- 实现Runnable接口
- 静态本地方法registerNatives,注册本地系统资源
- 成员变量: 线程名称/优先级/id/任务target(Runnable)/线程状态/分组/线程内部锁blockerLock
- 线程状态枚举State
TODO 状态流转图补充 - 构造方法: 都会调用init方法,init方法会继承父线程的相关属性
- 线程方法
-
重要方法示例
- run: 调用Runnable对象的run方法
- start: 同步方法,启动线程,启动前会校验线程状态是否为初始化状态—> 一个线程只能启动一次,多次启动会抛出异常
- sleep: 休眠线程一段时间.注意: 线程休眠后,不会释放相应的锁
- interrupt: 中断线程,通过设置线程中断标识位来中断线程.能使正在执行的任务能够继续执行完毕,而不像stop()方法那样强制线程关闭
- join
优化2: 使用线程池减少线程创建的开销,并管理线程
线程池的优点
- 减少线程创建销毁的频次,提升性能
- 实现了线程的统一管理
- 提供了更多的功能,例如定时执行,线程中断
核心类: Executors 和 ThreadPoolExecutor
Executors: 创建线程池的工具类
TreadPoolExecutor: 线程池的核心类之一
线程池的状态
- Running: 运行状态
- Shutdown: 中止桩体
- Stop: 停止状态
- Tidying: 整洁状态
- Terminated: 终止状态
TODO 状态流转图补充
线程池的构造方法的参数
- 核心线程数
- 最大线程数
- 空闲线程存活时间
- 空闲线程存活时间单位
- 线程工厂: 线程工厂的功能就是生产线程. 自定义线程工厂最重要的功能就是设置线程名称,方便多线程调试
- 阻塞队列: 用来存储等待处理的任务
- 拒绝处理任务时的策略
优化3: 使用并发辅助类实现线程池中的多个线程结果的控制
AQS中的CountDownLatch、Semaphore、CyclicBarrier
CountDownLatch
- 同步辅助类,通过它可以阻塞当前线程。
- 也就是说,能够实现一个线程或者多个线程一直等待,直到其他线程执行的操作完成。
- 使用一个给定的计数器进行初始化,该计数器的操作是原子操作,即同时只能有一个线程操作该计数器。
Semaphore
- 控制同一时间并发线程的数目。能够完成对于信号量的控制,可以控制某个资源可被同时访问的个数。
- 比如:数据库连接数。
CyclicBarrier
- 可以用于多线程计算数据,最后合并计算结果的场景