shutdown 和 shutdownNow 有啥不一样?一文看懂 Java 线程池关闭方式

原文来自于:zha-ge.cn/java/59

shutdown 和 shutdownNow 有啥不一样?一文看懂 Java 线程池关闭方式

咱们今天聊个特别接地气但偏偏容易迷糊的小选手:Java 线程池的 shutdown 和 shutdownNow。说实话,这俩名字一看就像是亲兄弟,放一个班级里绝对同桌,搞不好连饭都抢对方的。但等真用起来,它们的"性格"完全不一样------突然暴躁、温柔劝退,简直戏精。下面就让我给大家唠唠我亲身见识到的这些"程池兄弟"的故事。

线程池要收工,总不能一拍脑袋就走吧

有一天,产品经理说:有些活儿做完就别干了,省点儿资源,回家睡觉吧。我拍拍胸脯,"线程池有 shutdown,交给我!"当时以为,这不就一个方法名吗?关门熄灯,就结束呗。

然后我顺手加了一句:

java 复制代码
executorService.shutdown();
// 后面以为线程池就干干净净歇菜

页面一刷新,诶,怎么新来的任务还会被拒绝?可惜没多想,觉得挺合理的。本以为生活继续,突然有小伙伴说:你要是急着下班,shutdownNow 你试过没,会有啥新花样?

踩坑瞬间

我一拍脑门,试试呗,反正羊毛出在羊身上,bug谁没写过!于是我加上这行让人心跳加速的代码:

java 复制代码
List<Runnable> notStarted = executorService.shutdownNow();
// 打印一下看看没被执行的任务都有哪些
System.out.println("没来得及干的任务: " + notStarted);

初衷就一个:马上收工!全部停摆!结果一跑,发现事情不太对------不是所有正在干活的线程都立刻停住了。还有,某些任务卡着卡着突然 InterruptedException 飞出来,把业务流程搅和得一团糟。

最绝的是,队列里没执行的 Runnable 干脆给我吐出来了,一堆"遗留作业"等我补锅。刚加完 shutdownNow,就炸出一屋子 Exception,自测直接红。

于是我回去看源码和官方注释,这才明白:

  • shutdown():温柔派,只是告诉线程池,"兄弟们,不接新活了,干完手头的项目都回家。"
  • shutdownNow():大喇叭,直接喊停!正在干的线程发个 interrupt(但不保证真的秒停),还把队列里没开始的活扔回给你认领。

用 shutdown 还是 shutdownNow,一不留神全家桶

基于我那次"有惊无险"的实际体验,各位兄弟姐妹谨记:

方法 行为简述 线程状态 队列处理
shutdown 拒绝新任务,等老任务做完 继续执行 手尾能收干净
shutdownNow 试图强停、interrupt 在跑的 不一定立刻终止 返回所有未开始任务

就像点外卖选"温和收餐"还是"暴力催单",各有风险。你要是任务非原子、容易响应中断还好,要是不理 interrupt,shutdownNow 就能让你见识"死机全家桶"。

有一次我调度一个处理大文件的线程,用 shutdownNow,以为它能直接砍掉。结果对方压根不接中断信号,文件没处理完线程根本死不了。经理骂娘,说程序员光会拍脑袋写代码。

经验启示

这玩意儿的教训,我给大家总结几点,免得大家踩我的坑:

  • 优先用 shutdown,让线程池优雅退休,不要一上来就暴力赶人。
  • shutdownNow 真的只适合应急,比如线上事故、关机那种生死存亡时刻。
  • 队列里未执行的任务,用 shutdownNow 可以收集处理,但记得别随便丢,还是得业务善后。
  • 如果你的线程里逻辑根本不 care interrupt,那 shutdownNow 的"猛男操作"形同虚设。
  • 想要线程真的停,实际得让任务响应 Thread.interrupt(),不然它还是坚挺到底。

细心如我,最后贴段伪代码冷静分析:

java 复制代码
for (Runnable task : notStarted) {
    // 做善后处理,比如重试、丢弃或者报警提醒
    handleLeftTask(task);
}

生活已经很难了,线程池能不暴力就不暴力,"慢慢收场"永远都比"突然杀青"大家好过。今天就先聊到这儿,各位别深夜 shutdownNow,梦里都得被线程 interrupt 吓醒!

相关推荐
山岚的运维笔记10 分钟前
SQL Server笔记 -- 第20章:TRY/CATCH
java·数据库·笔记·sql·microsoft·sqlserver
南极企鹅32 分钟前
springBoot项目有几个端口
java·spring boot·后端
清风拂山岗 明月照大江38 分钟前
Redis笔记汇总
java·redis·缓存
xiaoxue..1 小时前
合并两个升序链表 与 合并k个升序链表
java·javascript·数据结构·链表·面试
忧郁的Mr.Li1 小时前
SpringBoot中实现多数据源配置
java·spring boot·后端
yq1982043011561 小时前
静思书屋:基于Java Web技术栈构建高性能图书信息平台实践
java·开发语言·前端
一个public的class1 小时前
你在浏览器输入一个网址,到底发生了什么?
java·开发语言·javascript
有位神秘人1 小时前
kotlin与Java中的单例模式总结
java·单例模式·kotlin
golang学习记2 小时前
IntelliJ IDEA 2025.3 重磅发布:K2 模式全面接管 Kotlin —— 告别 K1,性能飙升 40%!
java·kotlin·intellij-idea
爬山算法2 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
java·压力测试·hibernate