Skip to content

线程池有几种状态?

约 813 字大约 3 分钟

多线程与并发快手

2025-03-19

⭐ 题目日期:

快手 - 2024/12/29

📝 题解:

线程池的状态通常用于管理其生命周期,确保任务能够被合理调度和资源得到有效回收。以Java中的ThreadPoolExecutor为例,线程池共有以下五种状态:


1. RUNNING(运行中)

  • 状态值RUNNING(数值表示的高3位为 111
  • 特点
    • 接受新任务:可以继续提交新的任务。
    • 处理队列任务:执行已提交到任务队列中的任务。
    • 正常工作模式:线程池初始化后的默认状态。
  • 状态转换
    • 调用 shutdown() → 进入 SHUTDOWN
    • 调用 shutdownNow() → 进入 STOP

2. SHUTDOWN(关闭中)

  • 状态值SHUTDOWN(高3位为 000
  • 特点
    • 不再接受新任务:新提交的任务会被拒绝(触发 RejectedExecutionException)。
    • 处理现有任务:继续执行任务队列中已存在的任务。
    • 优雅关闭:适用于希望平稳结束任务的场景。
  • 状态转换
    • 任务队列为空且工作线程数为0 → 进入 TIDYING
    • 调用 shutdownNow() → 进入 STOP

3. STOP(停止)

  • 状态值STOP(高3位为 001
  • 特点
    • 立即中断任务:尝试停止所有正在执行的任务(通过 Thread.interrupt())。
    • 丢弃队列任务:不再处理任务队列中的任务,并返回未执行的任务列表。
    • 强制关闭:适用于需要立即释放资源的场景。
  • 状态转换
    • 所有工作线程终止 → 进入 TIDYING

4. TIDYING(整理中)

  • 状态值TIDYING(高3位为 010
  • 特点
    • 过渡状态:所有任务已终止,工作线程数为0。
    • 执行钩子方法:调用 terminated() 方法(用户可覆盖此方法进行自定义清理)。
  • 状态转换
    • terminated() 执行完毕 → 进入 TERMINATED

5. TERMINATED(已终止)

  • 状态值TERMINATED(高3位为 011
  • 特点
    • 最终状态:线程池完全关闭,不再响应任何操作。
    • 资源释放:所有资源(如线程、队列)已回收。

状态转换示意图

RUNNING → shutdown() → SHUTDOWN → 队列空且线程数为0 → TIDYING → terminated() → TERMINATED

  └→ shutdownNow() → STOP → 线程数为0 → TIDYING → terminated() → TERMINATED

关键设计点

  1. 状态位编码: Java使用 AtomicInteger 的高3位表示状态,低29位表示工作线程数,通过位运算高效管理状态和线程数。

    private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
    private static final int COUNT_BITS = 29;
    private static final int CAPACITY = (1 << COUNT_BITS) - 1;
    
    // 状态常量
    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;
  2. 拒绝策略: 在 SHUTDOWNSTOP 状态下提交任务会触发拒绝策略(如抛出异常、丢弃任务等)。


实际应用场景

  • RUNNING:正常处理高并发请求。
  • SHUTDOWN:服务重启前等待存量任务完成。
  • STOP:紧急终止服务,避免资源泄漏。
  • TERMINATED:线程池彻底销毁,释放JVM资源。

总结

线程池的五种状态(RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED)共同管理其生命周期,确保任务调度和资源回收的安全性。理解这些状态及其转换逻辑,有助于合理使用线程池并避免常见问题(如任务丢失、资源泄漏)。