shutdown()温和收尾,拒绝新任务但执行完已提交任务;shutdownNow()强制中断并清空队列,效果取决于任务是否响应中断。

Java 线程池中 shutdown() 和 shutdownNow() 都用于关闭线程池,但行为逻辑完全不同:前者是“等任务跑完再关门”,后者是“拉闸断电+清场”。关键不在“停不停”,而在“怎么收尾”。
shutdown():温和收尾,保障任务完整性
调用后线程池进入 SHUTDOWN 状态:
- 立即拒绝新任务(
submit()/execute()抛RejectedExecutionException) - 正在执行的任务继续运行,队列中已提交但未开始的任务也会被逐个取出执行
- 只中断空闲线程(不打断正在跑任务的线程),不主动调用
interrupt() - 线程池不会自动阻塞等待——必须配合
awaitTermination()才算真正关到位
shutdownNow():强制干预,侧重响应速度
调用后线程池进入 STOP 状态:
- 同样拒绝新任务
- 对所有工作线程调用
Thread.interrupt(),试图中断正在执行的任务 - 直接清空任务队列,返回未执行的
Runnable列表(注意:不是原始任务对象,可能被包装) - 不保证任务一定停止——若任务没检查中断状态、没调用可中断方法(如
sleep()、wait()、BlockingQueue.take()),interrupt()就无效
实际关闭必须组合使用
单独调用任一方法都不算“关好”:
立即学习“Java免费学习笔记(深入)”;
- 只调
shutdown()不等,主线程可能退出,后台任务还在跑 - 只调
shutdownNow()不等,无法确认是否真终止,线程可能残留 - 推荐三步闭环:先 shutdown() → 再 awaitTermination() 等待 → 超时后 shutdownNow() 强制兜底
任务是否响应中断,决定 shutdownNow 是否有效
这是最常被忽略的核心前提:
- 有效场景:任务中有
Thread.sleep(1000)、queue.poll(5, SECONDS)、lock.lockInterruptibly()等可中断操作,且捕获了InterruptedException并及时退出 - 无效场景:纯计算循环未检查
Thread.currentThread().isInterrupted(),或阻塞在无超时的Socket.read()、synchronized锁上 - 简单验证方式:在任务开头加
if (Thread.currentThread().isInterrupted()) return;,再配合shutdownNow()测试


















