线程池状态
- RUNNING:正常的状态:接受新的任务,处理等待队列中的任务
- SHUTDOWN:不接受新的任务提交,但是会继续处理等待队列中的任务
- STOP:不接受新的任务提交,不再处理等待队列中的任务,中断正在执行任务的线程
- TIDYING:所有的任务都销毁了,workCount 为 0。线程池的状态在转换为 TIDYING 状态时,会执行钩子方法 terminated()
- TERMINATED:terminated() 方法结束后,线程池的状态就会变成这个
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
// COUNT_BITS 设置为 29(32-3),前三位用于存放线程状态,后29位用于存放线程数
// 00000000000000000000000000011101
private static final int COUNT_BITS = Integer.SIZE - 3;
// 000 11111111111111111111111111111
// 线程池的最大线程数是 2^29-1=536870911
// 减1之后高三位为 0,其他为1
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
// runState is stored in the high-order bits
// 线程池的状态存放在高 3 位中
// 11100000000000000000000000000000
private static final int RUNNING = -1 << COUNT_BITS;
// 00000000000000000000000000000000
private static final int SHUTDOWN = 0 << COUNT_BITS;
// 00100000000000000000000000000000
private static final int STOP = 1 << COUNT_BITS;
// 01000000000000000000000000000000
private static final int TIDYING = 2 << COUNT_BITS;
// 01100000000000000000000000000000
private static final int TERMINATED = 3 << COUNT_BITS;
// Packing and unpacking ctl
// & 两个数都为1则为1,否则为0
// 将整数 c 的低 29 位修改为 0,就得到了线程池的状态
// ~CAPACITY 111 00000000000000000000000000000
private static int runStateOf(int c) { return c & ~CAPACITY; }
// 将整数 c 的高 3 为修改为 0,就得到了线程池中的线程数
// CAPACITY 000 11111111111111111111111111111
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
shutdown()
关闭线程池,已提交的任务继续执行,不接受继续提交新任务。
shutdownNow()
shutdownNow相对于shutdown的加强版,区别在于它会去停止当前正在进行的任务。
关闭线程池,尝试停止正在执行的所有任务,不接受继续提交新任务。
返回任务队列中正在等待的所有任务转移到一个 List ,此时可以进行其他操作。
判断线程池是否关闭
isShutdown()
线程是否开始执行了shutdown方法。
当isShutdown返回true并不代表这个线程池是关闭状态了,只代表着线程有没有开始执行线程关闭的方法。
isTerminated()
如果调用了 shutdown() 或 shutdownNow() 方法后,所有任务结束了,那么返回true。
这个方法必须在调用shutdown或shutdownNow方法之后调用才会返回true。
awaitTermination()
等待所有任务完成,并设置超时时间。
实际应用中是,先调用 shutdown 或 shutdownNow,再调这个方法等待所有的线程真正地完成,返回值意味着有没有超时。
代码
shutdown();
List<Runnable> list = shutdownNow()
protected void cancelRemainingTask(Runnable task) {
if (task instanceof Future) {
((Future<?>) task).cancel(true);
}
}
private void awaitTerminationIfNecessary(int awaitTerminationSeconds) {
if (this.awaitTerminationSeconds <= 0) {
return;
}
try {
if (!awaitTermination(this.awaitTerminationSeconds, TimeUnit.SECONDS)) {
log.warn("等待线程池终止超时");
}
} catch (InterruptedException ex) {
log.warn("等待线程池终止超时被打断");
Thread.currentThread().interrupt();
}
}