一, ThreadPoolExecutor执行流程
二, ThreadPoolExecutor状态
线程池中核心属性 ctl
//ctl本质就是一个int类型的数值
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// COUNT_BITS = 32 - 3 = 29
// ctl表述了两个状态
// 1. 标识线程池当前的状态(高三位)
// 2. 标识线程池当前的工作线程个数(低29位)
private static final int COUNT_BITS = Integer.SIZE - 3;
// 表述了工作线程的最大数量
private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
// 线程池的5种状态
// 111
private static final int RUNNING = -1 << COUNT_BITS;
// 000
private static final int SHUTDOWN = 0 << COUNT_BITS;
// 001
private static final int STOP = 1 << COUNT_BITS;
// 010
private static final int TIDYING = 2 << COUNT_BITS;
// 011
private static final int TERMINATED = 3 << COUNT_BITS;
// c就是ctl,计算出当前线程池的状态,即高三位和后29位为0
private static int runStateOf(int c) { return c & ~COUNT_MASK; }
// 计算当前线程池中的工作线程个数
private static int workerCountOf(int c) { return c & COUNT_MASK; }
- 线程池创建后处理RUNNING 状态
- 调用shutdown()方法后处理SHUTDOWN状态,线程池不能接受新的任务,清除一些空闲worker,会等等阻塞队列的任务完成。
- 调用shutdownNow()方法后,处于STOP状态,线程池不能接受新的任务,中断所有线程,阻塞队列中没有被执行的任务全部丢弃。此时,poolsize=0,阻塞队列的size也是0。
- 当所有的任务已经终止,ctl记录的“任务数量”为0,线程池会变为TIDYING状态。接着会执行terminated()函数。
- 线程池处在TIDYING状态时,执行完terminated()方法之后,就会由TIDYING -> TERMINATED,线程池被设置为 TERMINATED状态。
三, Execute方法
public void execute(Runnable command) {
//非空判断
if (command == null)
throw new NullPointerException();
// 获取ctl属性
int c = ctl.get();
// 计算工作线程个数,是否小于核心线程数
if (workerCountOf(c) < corePoolSize) {
// 如果小于,添加核心线程去执行(true表示是核心线程)
if (addWorker(command, true))
// 添加核心线程成功,返回true,直接return结束
return;
// 如果在并发情况下,添加核心线程失败的线程,需要重新获取一次ctl属性
c = ctl.get();
}
// 也就是创建核心线程失败,判断当前线程池状态是否是RUNNING
// 如果不小于核心线程数,则将任务添加到workQueue工作队列
if (isRunning(c) && workQueue.offer(command)) {
// 添加到队列成功
int recheck = ctl.get();
// 判断线程池是否是RUNNING状态,如果isRunning返回false,则表明线程池当前状态不接受任务,
// 则remove这个任务,然后执行拒绝策略
if (! isRunning(recheck) && remove(command))
//执行拒绝策略(线程池状态不正确)
reject(command);
// 线程池是running或者移除任务失败,判断工作线程是否为0,
else if (workerCountOf(recheck) == 0)
// 工作线程数为0,但是工作队列中有任务在排队,则任务无人处理
// 添加一个空任务,非核心线程,为了处理在工作队列中排队的任务
addWorker(null, false);
}
// 添加到任务队列失败,则创建非核心线程执行任务
// 如果这时创建非核心线程失败(当前线程不小于maximumPoolSize时),就会执行拒绝策略
else if (!addWorker(command, false))
reject(command);
}