Java中对线程池构造方法ThreadPoolExecutor机理的简单理解(精简)
话不多说奔主题,精神抖擞就是干!
1. 所在包:java.util.concurrent
2. 源码片段
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
if (corePoolSize < 0 || maximumPoolSize <= 0 || maximumPoolSize < corePoolSize || keepAliveTime < 0) throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null) throw new NullPointerException();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
3. 各个击破
参数名 作用
corePoolSize 核心线程池大小,即固定线程数
maximumPoolSize 最大线程池大小,即核心线程数+动态增加的线程数(非核心线程)
keepAliveTime 线程池中动态增加的线程(maximumPoolSize - corePoolSize)在空闲时候的最大存活时间;
核心线程可以通过allowCoreThreadTimeOut(true)启用该时间
TimeUnit keepAliveTime的时间单位
workQueue 阻塞任务队列
threadFactory 新建线程工厂
RejectedExecutionHandler 当提交的任务数超过workQueue+maxmumPoolSize之和时,
后续任务会交给RejectedExecutionHandler来处理
4. 任务处理流程
创建核心线程---》等待任务处理---》核心线程任务饱和---》将后续任务丢进阻塞队列---》阻塞队列塞满---》创建非核心线程处理阻塞队列中的任务(动态增加的线程数不超过maximumPoolSize - corePoolSize)---》非核心线程任务饱和---》调用RejectedExecutionHandler处理后续任务---》非核心线程空闲并且超过keepAliveTime---》销毁非核心线程
5. 线程池的五种状态
Running:能接受新任务,以及处理已经添加的任务。
ShutDown:不接受新任务,可以处理已经添加的任务。
Stop:不接受新任务,不处理已经添加的任务,并且中断正在处里的任务。
Tidying:当所有任务已经终止了,ctl(负责记录线程池的运行状态与活动线程数)内部成员变量记录的任务数将变为0。
Terminated:线程池彻底终止。
6. 如何合理分配线程数量(一般N = CPU内核数 = 核心线程数)
6.1 CUP(计算)密集型:N + 1
6.2 IO(读写)密集型:2N + 1
6.3 综合型:N * (1 + WT) / ST
WT:线程等待时间
ST:线程运行时间
欢迎看官儿们留言补充和指正,谢谢下次见!