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

相关推荐
李少兄3 小时前
@DateTimeFormat.fallbackPatterns 详解
java
天天摸鱼的java工程师3 小时前
线上服务无辜假死状态:一次 GC Overhead 的深度排查
java·后端
程序员清风3 小时前
快手二面:Redisson公平锁用用过吗?他的实现原理是什么样子的?
java·后端·面试
SimonKing3 小时前
Java序列化陷阱揭秘:这5个错误80%的开发者都犯过
java·后端·程序员
Seven973 小时前
Redis容量评估模型
java·redis
€8113 小时前
Java入门级教程16——JUC的安全并发包机制
java·开发语言·juc的安全并发包机制·栅栏机制·闭锁机制·信号量机制·无锁机制
杨杨杨大侠3 小时前
Atlas Mapper 教程系列 (2/10):环境搭建与项目初始化
java·开源·github
杨杨杨大侠3 小时前
Atlas Mapper 教程系列 (1/10):框架概述与设计思路
java·开源·github