目录
一、什么是线程池
简单来讲:是一种创建、管理、回收线程的机制。
二、大体流程
在其内部维护了若干个线程,没有任务的时候,这些线程都处于等待空闲状态。如果有新的 线程任务,就分配一个空闲线程执行。如果所有的线程都处于忙碌状态,线程池会创建一个新线程进行 处理或者放入工作队列中等待。
三、创建线程池涉及的类和接口【Java标准库提供】
1.ExecutorServiice接口:进行线程池的访问操作
2.Executors类:创建线程池的工具类
3.ThreadPoolExecutor及其子类:封装线程池的核心参数和运行机制
四、执行流程
核心流程:核心线程---->工作队列------>非核心线程---->拒绝策略
一切从提交线程任务开始
1.线程池会在线程池中分配一个空闲线程,用于执行线程任务
2.如果线程池中不存在空闲线程,再进行判断当前“存活的线程数”是否小于核心线程数
3. 判断是否大于核心线程数
- 若小于核心线程数,线程池会创建一个新线程去处理任务
- 若大于核心线程数,线程池会检查工作队列
4. 判断工作队列是否饱和
- 若工作队列未满,则将线程任务放入工作队列中进行等待。
注意:如果出现空闲线程,将从工作队列中按照FIFO规则取出线程任务并分配执行
- 若工作队列已满,则判断线程数是否达到最大线程数
5.判断是否达到最大线程池
- 若当前“存活线程数 ”没有达到最大线程数,则创建一个新线程执行新线程任务
- 若当前“存活线程数 ”已经达到最大线程数,此时线程池已经饱和,将会采用拒绝策略处理新线程任务
五、创建线程池的4个参数
1.corePoolSize 线程池核心线程数
2.maximumPoolSize 最大线程数
3.keepAliveTime 非核心线程存活时间
TimeUnit: 参数KeepAliveTime的单位
4.BlockingQueue 阻塞工作队列
其他配置参数:
ThreadFactory 线程工厂
RejectedExecutionHandler 拒绝策略
中有:
A、ThreadPoolExecutor.AbortPolicy 默认策略 ,丢弃任务并抛弃
B、ThreadPoolExecutor.DiscardPolicy 丢弃任务,但不抛出异常
C、ThreadPoolExecutor.DiscartOldestPolicy 丢弃工作队列中的对头任务
【认为该任务已经失效】,将当前任务提交给线程池
D、ThreadPoolExecutor.CallerRunsPolicy:又原调用线程处理该任务【谁调用谁处理】
六、线程池涉及的状态
Running:运行状态
线程池一旦被创建,就处于该状态,且此时线程池中的任务数为0.
该状态的线程池会接受新任务,并处理工作队列中的任务
切换状态:调用下面的两个方法:
shutdown()方法 ------>SHUTDOWN状态
shutdownNow()方法 ----->STOP状态
SHUTDOWN:关闭状态
此时不会在接受新任务,但会将工作队列中所有任务处理完。
当工作队列为空时,线程池进入TIDYING状态。
STOP:停止状态
此时会中断正在运行的任务,不会处理工作队列中的任务,将未完成的任务返回
TIDYING:整理状态
表明所有的任务已经运行终止,记录的任务数量为0
TERMINATED:终止状态
表明线程池彻底关闭
七、Java标准库提供的4种常见线程池
将创建的方法封装到Executors工具类中
1、FixedThreadPool:线程数固定的线程池,使用Executors.newFixedThreadPool()创建;
2、CachedThreadPool:线程数根据任务动态调整的线程池,
使用 Executors.newCachedThreadPool()创建;
3、SingleThreadExecutor:仅提供一个单线程的线程池,
使用Executors.newSingleThreadExecutor()创建;
4、ScheduledThreadPool:能实现定时、周期性任务的线程池,
使用Executors.newScheduledThreadPool()创建:
八、线程池的优点
(1) 线程和任务分离,提升线程的重用性。
(2)控制线程的并发数量,降低服务器压力,统一管理所有的线程。
(3)提升系统的响应速度