文章目录
- 一、线程池状态分析
一、线程池状态分析
线程池的状态在 ThreadPoolExecutor
源码中定义 : private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0))
成员变量的 前
位是线程池的状态位 , 剩下的
位是线程数 ;
代码语言:javascript复制public class ThreadPoolExecutor extends AbstractExecutorService {
/**
* 主池控制状态ctl是一个原子整数
* 两个概念领域
* workerCount,指示有效线程数
* 运行状态,指示是否运行、关闭等
*
* 为了将它们打包成一个整数,我们将workerCount限制为
* (2^29)-1(约5亿)个线程,而不是(2^31)-1(2
* 10亿)否则可代表。如果这曾经是一个问题
* 将来,变量可以更改为原子长度,
* 下面的移位/遮罩常数已调整。但在需要之前
* 因此,此代码使用int更快更简单。
*
* workerCount是已注册的工人数
* 允许启动,不允许停止。该值可能是
* 与活动线程的实际数量暂时不同,
* 例如,ThreadFactory在以下情况下无法创建线程:
* 当退出线程仍在执行时
* 终止前的簿记。用户可见池大小为
* 报告为工作集的当前大小。
*
* 运行状态提供主要的生命周期控制,具有以下值:
*
* 正在运行:接受新任务和处理排队的任务
* 关机:不接受新任务,但处理排队的任务
* 停止:不接受新任务,不处理排队的任务,
* 并中断正在进行的任务
* 整理:所有任务都已终止,workerCount为零,
* 正在转换为状态整理的线程
* 将运行终止的()钩子方法
* 终止:终止()已完成
*
* 这些值之间的数字顺序很重要,以允许
* 有序比较。运行状态随时间单调增加
* 时间,但不需要击中每个状态。这些转变是:
*
* 运行->关机
* 在调用shutdown()时,可能隐式地在finalize()中
* (运行或关闭)->停止
* 在调用shutdownNow()时
* 关机->整理
* 当队列和池都为空时
* 停止->整理
* 当池为空时
* 清理->终止
* 当终止的()钩子方法完成时
*
* 等待终止()的线程将在
* 国家终止。
*
* 检测从关闭到清理的过渡较少
* 比您希望的简单,因为队列可能会
* 非空后为空,关机状态下为空,但
* 只有在看到它是空的之后,我们才能终止
* workerCount为0(有时需要重新检查——请参阅
* 下)。
*/
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; }
}
简单的机翻了下 , 如果查看详细的英文注释 , 查看 libcore/ojluni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java 源码 ;
RUNNING 状态 : 该状态下 可以接受新的 Runnable 任务 , 以及 处理阻塞队列中被添加的 Runnable 任务 ;
SHUTDOWN 状态 : 不接受新的 Runnable 任务 , 可以处理已经添加在阻塞队列中的 Runnable 任务 ;
STOP 状态 : 不接受新的 Runnable 任务 , 也不处理已经添加在阻塞队列中的 Runnable 任务 , 正在执行的任务也要中断 ;
TIDYING 状态 : 停止所有任务 , private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0))
变量设置为
;
TERMINATED 状态 : 线程池彻底停止 ;
在 RUNNING 状态 , 调用 shutdown()
方法 , 跳转到 SHUTDOWN 状态 , 如果此时阻塞队列为空 , 线程池的工作线程为
, 就自动进入到 TIDYING 状态 ;
这里的工作线程指的是 核心线程 和 非核心线程 ;
线程池处于 RUNNING 状态下 , 正常运行 , 既可以处理新任务 , 也可以处理阻塞队列中的任务 ; 一旦调用 shutdown()
方法后 , 不再接受新任务 , 将阻塞队列中的残留任务执行完毕 , 然后进入 TIDYING 状态 ;
在 RUNNING 状态 , 调用 shutdownNow()
方法 , 跳转到 STOP 状态 , 此时强行将线程池的工作线程 ( 核心线程 和 非核心线程 ) 和 阻塞队列清空 , 处理完毕后 , 跳转到 TIDUING 状态 ;
也就是说 , 不等待当前正在执行的任务和阻塞队列中的任务执行完毕 , 立刻跳转到 TIDYING 状态 ;
在 TIDYING 状态下 , 一般是自动跳转到 TERMINATED 状态 ;