当前位置: 首页 > news >正文

Java 线程池中 shutdown 与 shutdownNow 的区别是什么?

Java 线程池中 shutdownshutdownNow 的区别


  1. 核心行为差异
    | 方法 | 行为描述 |
    |----------------|----------------------------------------------------------------------------|
    | shutdown | 平缓关闭线程池:
    1. 停止接受新任务。
    2. 已提交的任务(包括队列中的任务)会继续执行完成。 |
    | shutdownNow | 强制关闭线程池:
    1. 停止接受新任务。
    2. 尝试中断正在执行的任务。
    3. 清空任务队列,并返回未执行的任务列表。 |

  1. 线程中断机制
  • shutdown

    • 不中断任何线程,正在执行的任务会继续运行直到完成。
    • 适用于需要确保所有已提交任务完整执行的场景(如数据持久化)。
  • shutdownNow

    • 向所有工作线程发送中断信号(调用 Thread.interrupt())。
    • 任务是否终止取决于代码逻辑:
      • 若任务未检查中断状态(如未捕获 InterruptedException),可能无法终止。
      • 示例:一个循环任务中未调用 Thread.currentThread().isInterrupted(),即使调用 shutdownNow,任务仍会继续运行。

  1. 任务队列处理
    | 方法 | 队列处理 | 返回值 |
    |----------------|----------------------------------------------------------------------------|------------------------------|
    | shutdown | 继续执行队列中所有任务。 | 无返回值。 |
    | shutdownNow | 移除并丢弃队列中所有未执行的任务,返回这些任务的列表(List<Runnable>)。 | 返回未执行任务的列表。 |

  1. 线程池状态变化
  • shutdown

    • 将线程池状态从 RUNNING 改为 SHUTDOWN
    • 最终状态会过渡到 TERMINATED(需所有任务执行完毕)。
  • shutdownNow

    • 将线程池状态从 RUNNING 改为 STOP
    • 最终状态过渡到 TERMINATED(无论任务是否全部完成)。

  1. 适用场景
    | 方法 | 典型场景 |
    |----------------|----------------------------------------------------------------------------|
    | shutdown | 需要确保所有任务完整执行(如数据库批量写入、日志归档)。 |
    | shutdownNow | 紧急终止线程池(如服务宕机前快速释放资源,或处理死锁任务)。 |

实战建议

  1. 优雅关闭的最佳实践:

    • 先调用 shutdown,再通过 awaitTermination 等待任务完成。
    • 若超时未完成,再调用 shutdownNow 强制终止。
    executor.shutdown();
    try {if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {executor.shutdownNow(); // 超时后强制终止 }
    } catch (InterruptedException e) {executor.shutdownNow();
    }
    
  2. 任务代码的容错设计:

    • 在任务中定期检查中断状态,确保能响应 shutdownNow
    public void run() {while (!Thread.currentThread().isInterrupted()) {// 执行任务逻辑 }
    }
    
  3. 监控与日志:

    • 记录 shutdownNow 返回的未执行任务列表,用于故障恢复或重试。

扩展:源码级逻辑

  • shutdown
    • 仅修改线程池状态为 SHUTDOWN,后续执行完队列任务后触发 terminate()
  • shutdownNow
    • 修改状态为 STOP,中断所有工作线程,并清空队列。
    • 源码片段:
      public List<Runnable> shutdownNow() {List<Runnable> tasks;final ReentrantLock mainLock = this.mainLock;mainLock.lock();try {checkShutdownAccess();advanceRunState(STOP);  // 状态改为STOP interruptWorkers();     // 中断所有线程 tasks = drainQueue();   // 清空队列并返回未执行任务 } finally {mainLock.unlock();}tryTerminate();return tasks;
      }
      

总结

  • shutdown 是“礼貌告别”,确保任务善后。
  • shutdownNow 是“强制清场”,适合紧急场景,但依赖任务代码的健壮性。
  • 关键选择点:是否需要保留未执行任务?能否容忍任务中途终止?
http://www.lryc.cn/news/547430.html

相关文章:

  • 基于Spring Boot的共享学习经验系统的设计与实现
  • 【简单的C++围棋游戏开发示例】
  • 单片机中的基础外设GPIO的知识和应用—(6)
  • 10-Agent循环分析新闻并输出总结报告
  • 十二、Redis Cluster(集群)详解:原理、搭建、数据分片与读写分离
  • 贪心算法解题框架+经典反例分析,效率提升300%
  • 策略设计模式-下单
  • Go加spy++隐藏窗口
  • React基础之tsx语法
  • 一体机:DeepSeek性能的“隐形枷锁”!
  • ALBEF的动量蒸馏(Momentum distillation)
  • 浏览器WEB播放RTSP
  • 将PDF转为Word的在线工具
  • 03. 对象的创建,存储和访问原理
  • 机器学习-GBDT算法
  • redis基础结构
  • 【keil】一种将STM32的armcc例程转换为armclang的方式
  • 计算机视觉算法实战——表面缺陷检测(表面缺陷检测)
  • window下的docker内使用gpu
  • Modbus协议(TCP)
  • 虚拟系统配置实验报告
  • Agentic系统:负载均衡与Redis缓存优化
  • 28-文本左右对齐
  • 建筑兔零基础自学python记录39|实战词云可视化项目——章节分布10(上)
  • Impacket工具中的横向渗透利器及其使用场景对比详解
  • 基于java,SpringBoot和Vue的医院药房药品管理系统设计
  • MQ保证消息的顺序性
  • cmake、CMakeLists.txt、make、ninja
  • 数据结构与算法 计算机组成 八股
  • RoboBrain:从抽象到具体的机器人操作统一大脑模型