目录
RUNNING、SHUNTDOWN、STOP、TIDYING、TERMINATED
本🐖在前几天介绍了有关线程池的核心配置参数以及线程池的执行流程,今天我们来了解线程池的状态
线程池的状态
线程池的状态分为:
RUNNING、SHUNTDOWN、STOP、TIDYING、TERMINATED
RUNNING:运行状态,线程池一旦创建,就处于RUNNING状态,并且线程池中的任务数为0。该状态的线程池会接收新任务,并处理工作队列的任务。
- 调用线程池的shutdown()方法,可以切换到SHUTDOWN关闭状态;
- 调用线程池的shutdownNow()方法,可以切换到STOP停止状态;
SHUTDOWN:关闭状态,该状态的线程池不会接受新任务,但会处理工作队列中的任务;
- 当工作队列为空时,并且线程池中执行的任务也为空时,线程池进入TIDYING状态;
STOP:停止状态,该状态的线程不会接收新任务,也不会处理阻塞队列中的任务,而且会中断正在运行的任务;
- 线程池中执行的任务为空,进入TIDYING状态;
TIDYING:整理状态,该状态表明所有的任务已经运行终止,记录的任务数量为0;
- terminated()执行完毕,进入TERMINATED状态;
TERMINATED:终止状态,该状态表示线程池彻底关闭。
使用场景
线程池的状态贯穿于线程池的创建、任务提交、线程管理、关闭销毁等全生命周期,具体在已下核心场景中被直接使用:
一、任务提交时:判断是否允许接收新任务
当你调用 executor.submit(task)
或 executor.execute(task)
提交任务时,线程池会先检查自身状态,决定是否接收任务:
-
如果状态是
RUNNING
:允许接收新任务,进入任务队列或分配线程执行。 -
如果状态是
SHUTDOWN
:不接收新任务,但会继续处理已在队列中的任务(避免新任务干扰 “正在收尾” 的过程)。 -
如果状态是
STOP
/TIDYING
/TERMINATED
:直接拒绝新任务(抛出RejectedExecutionException
)。
public void execute(Runnable command) {
if (command == null) throw new NullPointerException();
// 先获取当前线程池状态(与线程数打包在一个int变量中)
int c = ctl.get();
// 如果状态不是RUNNING,直接拒绝新任务
if (!isRunning(c)) {
reject(command);
return;
}
// 后续才是判断是否创建线程或加入队列...
}
二、线程池关闭时:控制关闭流程与资源清理
线程池的关闭方法(shutdown()
/shutdownNow()
)本质是通过修改状态触发不同的关闭逻辑:
-
shutdown()
:将状态改为SHUTDOWN
,不再接收新任务,但会等待队列中已有任务执行完毕,最后销毁线程。 -
shutdownNow()
:将状态改为STOP
,不仅不接收新任务,还会强制中断正在执行的线程,并清空任务队列(未执行的任务被返回)。
状态在这里的作用是 “标记关闭阶段”,确保关闭操作按规则执行(比如 SHUTDOWN
必须等队列任务完成,STOP
可以强制中断)。
三、工作线程运行时:决定是否继续处理任务
线程池中的核心线程 / 非核心线程(工作线程)会循环从任务队列中获取任务执行,而循环的终止条件完全由状态决定:
-
当状态是
RUNNING
:持续从队列取任务执行。 -
当状态是
SHUTDOWN
且队列已空:线程退出(因为没有新任务,且已有任务已处理完)。 -
当状态是
STOP
:无论队列是否有任务,线程直接退出(强制终止)。while (true) { // 检查当前状态:如果是STOP,或(SHUTDOWN且队列空),则线程退出 if (runStateAtLeast(ctl.get(), STOP) || (runState == SHUTDOWN && workQueue.isEmpty())) { break; // 线程销毁 } // 否则继续从队列取任务执行... }
四、线程池状态查询:监控与外部判断
-
线程池提供了
isRunning()
/isShutdown()
/isTerminated()
等方法,本质是通过查询状态给外部提供判断依据: -
例如,在任务执行前调用
isTerminated()
,如果返回true
(状态为TERMINATED
),则无需提交任务(避免被拒绝)。 -
监控系统可以通过状态判断线程池是否 “存活”“正在关闭” 或 “已销毁”,用于告警或资源调度。
总结:状态是线程池的 “指挥信号”
线程池的状态就像一个 “全局信号量”,所有核心操作(提交任务、线程运行、关闭清理)都需要先 “看信号行事”。它确保了线程池在并发环境下:
-
任务提交有明确的准入规则(避免无效提交);
-
关闭流程有明确的阶段划分(避免混乱的资源释放);
-
工作线程有明确的运行 / 终止条件(避免线程无意义空转或异常退出)。
没有状态的统一控制,线程池的并发安全和资源管理将完全失控(比如关闭时还在接收新任务,或线程一直空转浪费资源)。
肥嘟嘟左卫门就讲到这里啦,记得一键三连!!!😗