ThreadPoolExecutor
首先来看看线程池的主要工作流程图
接下来看看源码实现:
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
private static final int RUNNING = -1 << COUNT_BITS;
private static final int SHUTDOWN = 0 << COUNT_BITS;
private static final int STOP = 1 << COUNT_BITS;
private static final int TIDYING = 2 << COUNT_BITS;
private static final int TERMINATED = 3 << COUNT_BITS;
// Packing and unpacking ctl
private static int runStateOf(int c) { return c & ~CAPACITY; }
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
AtomicInteger的ctl变量,用低29位表示线程个数,高3位表示线程池状态;
- RUNNING :高三位:111,此时的线程池会接收任务,并处理阻塞队列中的任务;这里注意它其实是最小的
- SHUTDOWN:高三位:000,此时的线程池不会接收新的任务,但会处理阻塞队列中的任务。
- STOP:高三位:001,不接受新的任务,也不处理阻塞队列中的任务,而且中断正在执行的任务。
- TIDYING:010
- TERMINATED:011
我们使用Executor的execute(Runnable task)提交任务,但是它没有返回值,无法判断任务执行情况;而ExecutorService的submit(Callable task),返回Future,我们通过它来判断任务是否执行成功;
execute
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
//到这里说明状态为Running,任务也已经加入队列,workerCountOf(recheck) == 0代表线程池里并没有线程,
//addWorker(null, false),任务传null,意思是创建新线程来处理队列中的任务
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
- workerCountOf(c)获取低29位,也就是线程数,如果小于核心线程数,则调用addWork方法创建线程执行任务;否则执行步骤2
- 若当前线程池状态是RUNNING,则将任务添加到阻塞队列workQueue.offer(command)非阻塞,执行步骤3,否则执行步骤4;
- 由于加入队列操作的耗时,所以加进队列后会对当前线程池状态再次进行判断,若不在是RUNNING,则从队列中删除任务,再调用handler处理任务;
- addWorker(command, false)创建线程执行任务,执行失败则调用handler处理任务;
addWork
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);