在 Java 中,线程池(ThreadPoolExecutor)的生命周期状态是由其内部状态机管理的,主要通过 ctl
(control)变量来跟踪线程池的运行状态和线程数量。线程池的生命周期状态有以下几种,分别对应不同的运行阶段:
线程池的生命周期状态
-
RUNNING(运行状态)
- 描述: 这是线程池的初始状态,表示线程池可以接受新任务,并且会处理队列中的现有任务。
- 条件 :
- 新提交的任务会被分配给线程执行。
- 如果核心线程数未达到上限,会创建新线程。
- 如果核心线程数已满,且任务队列未满,任务会被加入队列。
- 状态值 :
RUNNING
的状态值在ctl
中是负数(最高位为 0)。
-
SHUTDOWN(关闭状态)
- 描述: 线程池不再接受新的任务,但会继续执行队列中已有的任务以及正在运行的任务。
- 触发方式 : 调用
shutdown()
方法。 - 条件 :
- 新提交的任务会被拒绝(抛出
RejectedExecutionException
)。 - 线程池会等待所有任务执行完毕后进入终止状态。
- 新提交的任务会被拒绝(抛出
- 状态值 :
SHUTDOWN
的状态值为 0。
-
STOP(停止状态)
- 描述: 线程池不再接受新任务,也不会继续处理队列中的任务,并且会尝试中断正在执行的任务。
- 触发方式 : 调用
shutdownNow()
方法。 - 条件 :
- 返回队列中未执行的任务列表。
- 正在运行的线程会被中断(通过
interrupt()
)。
- 状态值 :
STOP
的状态值为 1。
-
TIDYING(整理状态)
- 描述: 这是线程池的一个过渡状态,表示所有任务都已经完成(或被中断),线程池正在准备进入终止状态。
- 条件 :
- 在
SHUTDOWN
状态下,任务队列为空且活动线程数为 0。 - 在
STOP
状态下,活动线程数为 0。
- 在
- 状态值 :
TIDYING
的状态值为 2。 - 行为 : 线程池会调用
terminated()
方法(可由开发者重写)来执行清理工作。
-
TERMINATED(终止状态)
- 描述: 线程池完全终止,不再有任何活动。
- 条件 : 从
TIDYING
状态转换而来,terminated()
方法执行完毕后进入此状态。 - 状态值 :
TERMINATED
的状态值为 3。 - 行为: 线程池资源被释放,无法再恢复使用。
状态转换流程
以下是线程池状态的典型转换路径:
RUNNING
→SHUTDOWN
: 调用shutdown()
方法。RUNNING
→STOP
: 调用shutdownNow()
方法。SHUTDOWN
→TIDYING
: 任务队列为空且所有线程完成任务。STOP
→TIDYING
: 所有线程被中断或完成。TIDYING
→TERMINATED
:terminated()
方法执行完毕。
代码中的体现
在 ThreadPoolExecutor
的源码中,状态是通过 ctl
的高 3 位来表示的(基于位运算)。例如:
java
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
private static final int COUNT_BITS = Integer.SIZE - 3; // 29位用于线程计数
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;
示例代码
以下是一个简单的线程池生命周期演示:
java
import java.util.concurrent.*;
public class ThreadPoolDemo {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 4, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(2));
// 提交任务
for (int i = 0; i < 5; i++) {
executor.execute(() -> {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " 执行任务");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
// 关闭线程池
executor.shutdown(); // 进入 SHUTDOWN 状态
// executor.shutdownNow(); // 进入 STOP 状态
try {
executor.awaitTermination(5, TimeUnit.SECONDS); // 等待终止
System.out.println("线程池已终止: " + executor.isTerminated());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}