版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
该文章的主要目的是为了介绍execute方法的主要逻辑,还讨论了线程池的增长
线程的工作线程和任务的提交执行受到线程池状态的影响,情况颇为复杂,不过总结起来,梳理清楚,不禁大赞doug lea。(流程图好难画啊)
execute的源码如下:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
//判断核心线程数量
if (workerCountOf(c) < corePoolSize) {
// 使用corePoolSize扩充线程池
if (addWorker(command, true))
return;
//添加失败
c = ctl.get();
}
//1、线程创建失败
//2、线程池SHUTDOWN状态
// workQueue.offer(command) 队列饱和
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
// 线程池状态不是RUNNING 且 移除成功
if (! isRunning(recheck) && remove(command))
reject(command);
// 线程池为工作状态 或 移除失败,需要有工作线程执行移除失败的任务的任务
else if (workerCountOf(recheck) == 0)
//因为firstTask为空是为了添加一个没有任务的线程再从workQueue获取task,而workQueue为空,说明添加无任务线程已经没有意义,这应该是最后移除任务的保险
addWorker(null, false);
}
// 使用maxPoolSize扩充线程池
else if (!addWorker(command, false))
reject(command);
}
如果一个线程池为空,大致会通过如下流程增长:
1、添加核心线程;
2、如果核心线程已满,工作任务入队;
3、如果工作任务队列已满,说明核心线程的数量无法及时处理当前过饱和工作任务队列,添加工作线程;