shutdown()温和停机,拒绝新任务但执行完已提交任务;shutdownnow()立即中断运行任务、清空队列并返回剩余任务,适用于需快速释放资源的场景。

Java 中线程池的 shutdown() 和 shutdownNow() 都是用来关闭线程池的方法,但行为完全不同,选错可能导致任务丢失或线程无法释放。
shutdown():温和停机,等待已提交任务完成
调用 shutdown() 后,线程池不再接受新任务(后续提交会抛 RejectedExecutionException),但会继续执行已加入队列中且尚未开始的任务,以及正在运行中的任务。线程池进入“关闭中”状态,直到所有任务都完成,才真正终止。
常用配合方式:
- 调用
shutdown()后,通常接着调用awaitTermination(long timeout, TimeUnit unit)等待线程池自然结束 - 如果超时未结束,可再考虑是否调用
shutdownNow() - 示例:
executor.shutdown(); try { if (!executor.awaitTermination(10, TimeUnit.SECONDS)) { executor.shutdownNow(); } } catch (InterruptedException e) { executor.shutdownNow(); Thread.currentThread().interrupt(); }
shutdownNow():立即中断,尽力停止所有活动任务
shutdownNow() 会尝试停止所有正在执行的任务(通过调用线程的 interrupt()),同时清空任务队列,并返回尚未执行的任务列表。注意:它不保证任务一定被终止——如果任务未响应中断(比如没检查 Thread.interrupted() 或未捕获 InterruptedException),仍可能继续运行。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
适用场景:
- 需要快速释放资源,容忍部分任务未完成
- 已知任务支持中断(如使用
sleep、wait、BlockingQueue.take()等可中断阻塞操作) - 作为
shutdown()等待超时后的兜底操作
关键区别总结
核心差异不在“是否中断”,而在于对队列和运行中任务的处理策略:
-
shutdown():不中断运行中任务,不清理队列,只拒绝新任务 -
shutdownNow():尝试中断所有运行中任务,清空队列,返回剩余任务 - 两者都会将线程池状态设为
SHUTDOWN或STOP,之后再调用无效 - 无论哪种方式,线程池最终都需确保所有线程退出(如工作线程在任务结束后自行终止)
实际使用建议
标准关闭流程推荐组合使用:
- 先调用
shutdown(),给任务自然完成的机会 - 用
awaitTermination()设置合理超时(如几秒到几十秒,视任务性质而定) - 超时后调用
shutdownNow()做最后清理 - 始终在
finally或try-with-resources(若自定义了 AutoCloseable 封装)中执行关闭逻辑,避免遗漏
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










