【JDK 5】JUC 线程池

69 阅读2分钟

 一、作用:

1、减少频繁创建线程带来的消耗;
2、复用线程,可提高响应速度;
3、可以扩展线程管理功能,比如调优和监控。


二、核心概念

ThreadFactory :线程工厂
corePoolSize:核心线程数,最少的线程数量
maximumPoolSize:最大线程数
workQueue:待执行的任务队列
rejectedExecutionHandler :拒绝策略
keepAliveTime: 存活时间、当存在非核心线程且空闲时,超过存活时间就回收


三、生命周期

1、RUNNING 

状态说明:运行状态,接受新任务,处理已有任务。
状态切换: 线程池的初始化状态是RUNNING

2、SHUTDOWN

状态说明:关闭状态,不接受新任务,处理已有任务。
状态切换: 调用shutdown()时,线程池由RUNNING -> SHUTDOWN

3、STOP

状态说明:停止状态,不接受新任务,不处理已有任务。
状态切换: 调用shutdownNow()时,线程池由 (RUNNING or SHUTDOWN ) -> STOP

4、TIDYING

状态说明所有的任务已终止

状态切换
SHUTDOWN状态时,任务队列与线程无可执行任务时,SHUTDOWN -> TIDYING;
STOP状态时,线程无可执行任务时,STOP -> TIDYING

5、TERMINATED

状态说明线程池彻底终止
状态切换TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED

参考:线程池的五种状态及创建线程池的几种方式 - 知乎 (zhihu.com)


四、创建

1、Executors

//可缓存的线程池
Executors.newCachedThreadPool()
//单线程池
Executors.newSingleThreadExecutor()
//固定大小的线程池
Executors.newFixedThreadPool(5)
//定时线程数
Executors.newScheduledThreadPool(5)

不推荐
容易导致OOM,因为默认线程池的最大线程数Integer.MaxValue任务队列长度为Integer.MaxValue

2、ThreadPoolExecutor

new ThreadPoolExecutor(最小线程数, 最大线程数, 闲置线程存活时间, 时间单位, 等待任务队列, 线程工厂, 拒绝策略);

五、执行任务

1、execute

提交Runable任务

2、submit

提交Runnable / Callable任务,返回Future

3、invokeAny

提交Callable任务列表,返回一个成功结果

4、invokeAll

提交Callable任务列表,返回所有成功结果


六、执行流程

graph TD
A((提交任务)) --> B{核心线程<br>是否已满}
B --否--> C1(创建线程)
B --是--> C2{任务队列<br>是否已满}
C2 --否--> D1(加入任务队列)
C2 --是--> D2{是否达到<br>最大线程数}
D2--否--> E1(创建非核心线程)
D2--是--> E2((执行拒绝策略))

1、提交任务;
2、判断核心线程是否已满。不是就先创建线程,是则下一步;
3、判断任务队列是否已满,未满就加入任务队列,满了则下一步;
4、判断是否达到最大线程数,未达到则创建未核心线程,若已达到最大线程,则执行拒绝策略。


JDK8 新增

Executors.newWorkStealingPool()