线程池的状态
文章目录
- 线程池状态概述
- RUNNING状态
- SHUTDOWN状态
- STOP状态:强制停止期
- TIDYING状态:清理准备期
- TERMINATED状态
- 状态检查方法
- 监控线程池方法
- 总结
线程池状态概述
ThreadPoolExecutor使用一个32位的原子整数来同时存储线程池状态和工作线程数。高3位用于存储状态,低29位用于存储线程数。
// ThreadPoolExecutor源码中的状态定义
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;
这五种状态按照生命周期顺序分别是:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。
RUNNING状态
RUNNING是线程池创建后的初始状态,也是线程池的正常工作状态。
ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100)
);// 创建后就是RUNNING状态
executor.execute(() -> System.out.println("任务执行中"));
System.out.println("是否关闭:" + executor.isShutdown()); // false
System.out.println("是否终止:" + executor.isTerminated()); // false
从RUNNING状态出发,线程池可以转换到两个状态:
- 调用shutdown()方法转换到SHUTDOWN状态
- 调用shutdownNow()方法转换到STOP状态
SHUTDOWN状态
当调用shutdown()方法时,线程池进入SHUTDOWN状态,这是一种优雅的关闭方式。表示线程池开始关闭,但仍需要完成一些收尾工作:
- 不再接受新的任务提交
- 继续执行队列中已有的任务
- 等待所有任务完成后进入TIDYING状态
executor.shutdown();// 尝试提交新任务会被拒绝
try {executor.execute(() -> System.out.println("这个任务不会执行"));
} catch (RejectedExecutionException e) {System.out.println("任务被拒绝:" + e.getMessage());
}System.out.println("是否关闭:" + executor.isShutdown()); // true
System.out.println("是否终止:" + executor.isTerminated()); // 可能是false,取决于是否还有任务在执行
STOP状态:强制停止期
调用shutdownNow()方法会让线程池直接进入STOP状态,这是一种更加激进的关闭方式:
- 不接受新任务
- 中断正在执行的任务
- 清空任务队列并返回未执行的任务列表
List<Runnable> unfinishedTasks = executor.shutdownNow();
System.out.println("未完成的任务数:" + unfinishedTasks.size());
TIDYING状态:清理准备期
TIDYING是一个短暂的中间状态。当线程池满足以下条件时会自动进入此状态:
- 线程池处于SHUTDOWN状态且任务队列为空,所有任务执行完毕
- 线程池处于STOP状态且所有线程都已停止
在TIDYING状态下,线程池会调用terminated()方法,然后转换到TERMINATED状态。
// 自定义ThreadPoolExecutor来观察状态变化
ThreadPoolExecutor customExecutor = new ThreadPoolExecutor(2, 4, 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10)
) {@Overrideprotected void terminated() {System.out.println("线程池即将终止,执行清理工作");// 在这里可以做一些清理工作,比如释放资源、记录日志等super.terminated();}
};
TERMINATED状态
TERMINATED是线程池的最终状态,表示线程池已经完全关闭:
- 所有任务都已完成
- 所有工作线程都已停止
- terminated()方法已执行完毕
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
System.out.println("是否终止:" + executor.isTerminated()); // true
状态检查方法
ThreadPoolExecutor提供了几个方法来检查线程池状态:
// 检查是否已开始关闭(SHUTDOWN、STOP、TIDYING、TERMINATED)
boolean isShutdown = executor.isShutdown();// 检查是否完全终止(只有TERMINATED状态返回true)
boolean isTerminated = executor.isTerminated();// 检查是否正在终止过程中(SHUTDOWN或STOP状态)
boolean isTerminating = executor.isTerminating();
监控线程池方法
executor.getPoolSize()
executor.getActiveCount()
executor.getQueue().size()
executor.getCompletedTaskCount()
总结
线程池的状态管理是并发编程中的重要概念。五种状态各有其特定的作用:RUNNING保证正常工作,SHUTDOWN实现优雅关闭,STOP提供强制停止,TIDYING执行清理工作,TERMINATED表示完全结束。