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 吓醒!

相关推荐
chools4 小时前
【AI超级智能体】快速搞懂工具调用Tool Calling 和 MCP协议
java·人工智能·学习·ai
李白你好4 小时前
TongWeb EJB 反序列化生成工具(Java-Chain 插件)
java·安全
U盘失踪了5 小时前
Java 的 JAR 是什么?
java·jar
今天又在写代码6 小时前
java-v2
java·开发语言
competes6 小时前
慈善基金投资底层逻辑应用 顶层代码低代码配置平台开发结构方式数据存储模块
java·开发语言·数据库·windows·sql
2501_913061347 小时前
网络原理知识
java·网络
希望永不加班7 小时前
Spring AOP 代理模式:CGLIB 与 JDK 动态代理区别
java·开发语言·后端·spring·代理模式
flushmeteor8 小时前
java的动态代理和字节码生成技术
java·动态代理·代理·字节码生成
eggwyw8 小时前
基于SpringBoot和PostGIS的云南与缅甸的千里边境线实战
java·spring boot·spring
0xDevNull8 小时前
MySQL 别名(Alias)指南:从入门到避坑
java·数据库·sql