问题
(1)线程池的状态有哪些?
(2)各种状态下对于任务队列中的任务有何影响?
看源码线程池状态
ThreadPoolExecutor.class
// 状态控制 ctl的高三位保存运行状态
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//用二进制补码形式表示整型值的位数, 值为32-3
private static final int COUNT_BITS = Integer.SIZE - 3;
// 0010 0000 0000 0000 0000 0000 0000 0000, 一共32位
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
// 1110 0000 0000 0000 0000 0000 0000 0000
private static final int RUNNING = -1 << COUNT_BITS;
// 0000 0000 0000 0000 0000 0000 0000 0000
private static final int SHUTDOWN = 0 << COUNT_BITS;
// 0010 0000 0000 0000 0000 0000 0000 0000
private static final int STOP = 1 << COUNT_BITS;
// 0100 0000 0000 0000 0000 0000 0000 0000
private static final int TIDYING = 2 << COUNT_BITS;
// 0110 0000 0000 0000 0000 0000 0000 0000
private static final int TERMINATED = 3 << COUNT_BITS;
// 线程池的状态
private static int runStateOf(int c) { return c & ~CAPACITY; }
// 线程池中工作线程的数量
private static int workerCountOf(int c) { return c & CAPACITY; }
// 计算ctl的值,等于运行状态“加上”线程数量
private static int ctlOf(int rs, int wc) { return rs | wc; }
从上面可以看出:
- 线程池的状态一共有五种,分别是
- RUNNING
- 表示可接受新任务,且可执行队列中的任务
- SHUTDOWN
- 表示不接受新任务,但可执行队列中的任务
- STOP
- 表示不接受新任务,且不再执行队列中的任务,且中断正在执行的任务
- TIDYING
- 所有任务已经中止,且工作线程数量为0,最后变迁到这个状态的线程将要执行terminated()钩子方法,只会有一个线程执行这个方法
- TERMINATED
- 中止状态,已经执行完terminated()钩子方法
- RUNNING
- ctl的高三位保存运行状态,低29位保存工作线程的数量,也就是说线程的数量最多只能有(2^29-1)个,也就是上面的CAPACITY, 不是(2^31)-1
线程池的任务流转图:
过程:
- 新建时, 初始状态为RUNNING
- 执行shutdown()方法 —> 状态变为SHUTDOWN
- 执行shutdownNow()方法 —> 状态变为STOP
- shutdown()或shutdownNow()方法执行完毕, 且所有任务也已经终止, 工作中的线程数量为0 , 状态变为TIDYING
- 状态变为TIDYING后会有一个线程来执行terminated()钩子方法,最后状态变为终止状态TERMINATED
源码分析
1)RUNNING
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
2)SHUTDOWN
private final ReentrantLock mainLock = new ReentrantLock();
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// 检查是否有关闭权限
checkShutdownAccess();
//变更状态为SHUTDOWN
advanceRunState(SHUTDOWN);
// 标记空闲线程为中断状态
interruptIdleWorkers();
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
// shutdown 后尝试终止
tryTerminate();
}
3)STOP
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
//变更状态为STOP
advanceRunState(STOP);
interruptWorkers();
// 将任务队列加入到新的列表中返回
tasks = drainQueue();
} finally {
mainLock.unlock();
}
tryTerminate();
return tasks;
}
4)TIDYING
final void tryTerminate() {
for (;;) {
int c = ctl.get();
if (isRunning(c) ||
runStateAtLeast(c, TIDYING) ||
(runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
return;
// 工作线程数量不为0,不会执行后续代码
if (workerCountOf(c) != 0) { // Eligible to terminate
interruptIdleWorkers(ONLY_ONE);
return;
}
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// CAS修改状态为TIDYING状态
if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
try {
//执行terminated钩子方法
terminated();
} finally {
// CAS修改状态为TERMINATED状态
ctl.set(ctlOf(TERMINATED, 0));
termination.signalAll();
}
return;
}
} finally {
mainLock.unlock();
}
// else retry on failed CAS
}
}
修改状态为TIDYING后执行terminated()方法,最后修改状态为TERMINATED,标志着线程池真正消亡