shutdown温和停机,只拒新任务、保队列、不中断运行任务;shutdownNow强制中断,清空队列并尝试中断所有线程,但依赖任务响应中断。推荐先shutdown→awaitTermination→超时再shutdownNow。

shutdown 是温和停机,shutdownNow 是强制中断——两者根本区别不在“关不关”,而在“怎么关”和“关到哪一步”。
shutdown:任务队列照常执行,只停新任务
调用后线程池进入 SHUTDOWN 状态:
- 不再接受新提交的任务,后续
submit()或execute()会直接抛出RejectedExecutionException - 已入队但未开始执行的任务(比如在
LinkedBlockingQueue里排队的)全部保留,继续被空闲线程按序取出执行 - 正在运行的任务不受干扰,继续跑完;线程池不会主动中断任何工作线程
- 内部仅中断空闲线程(释放资源),不碰正在干活的线程
shutdownNow:清空队列 + 尝试中断所有运行中任务
调用后线程池立即进入 STOP 状态:
- 同样拒绝新任务
- 调用
drainQueue()物理清空任务队列,把所有未执行的Runnable批量移出,封装成List返回(队列长度瞬间归零) - 对每个工作线程调用
Thread.interrupt(),试图中断正在执行的任务 - 注意:中断只是“发信号”,能否真正停止取决于任务是否响应——比如检查
Thread.interrupted()、捕获InterruptedException或退出阻塞调用(如take()、sleep())
为什么不能只用 shutdownNow?
因为很多任务根本不响应中断:
立即学习“Java免费学习笔记(深入)”;
- 写了个死循环但没检查中断标志,
interrupt()毫无效果 - 用了
LockSupport.park()却没配合Thread.interrupted()判断 - 阻塞在 native IO(如 socket.read())或 synchronized 锁上,
interrupt()不会唤醒 - 此时
shutdownNow()返回非空列表,且isTerminated()长期为false,线程池实际关不干净
推荐关闭流程:三步闭环
一次可靠关闭必须包含:
- 先调
shutdown(),让系统进入有序收尾状态 - 再用
awaitTermination(30, TimeUnit.SECONDS)主动等待,给任务留出自然完成时间 - 若超时仍未终止,再调
shutdownNow()尝试兜底,并再次awaitTermination()确认最终状态


















