守护线程不会执行finally块。因其生命周期依附于非守护线程,JVM在所有非守护线程结束后立即退出,不等待守护线程完成、不触发finally、不调用shutdown hook,资源清理不可靠。

不一定会执行。
守护线程的生命周期不由自己决定
守护线程(Daemon Thread)存在的唯一目的是为其他非守护线程服务,比如垃圾回收、JIT 编译等。它的存续完全依赖于 JVM 中是否还有活跃的非守护线程。一旦所有非守护线程(包括 main 线程)结束,JVM 就会立即退出,**不会等待守护线程完成当前操作,更不会触发其 finally 块**。
- JVM 不会对守护线程做栈展开,也不调用 shutdown hook
- 线程上下文被直接标记为废弃,调度器停止分配 CPU 时间片
- 哪怕 finally 是下一行代码,控制流也根本来不及到达那里
典型场景:主线程退出后守护线程被“硬杀”
例如主线程启动一个守护线程后很快结束:
- 守护线程可能刚进入 try 块,甚至还没开始 sleep
- 主线程 return,JVM 检测到无非守护线程存活,立刻终止进程
- finally 中的资源关闭、日志打印、状态更新等全部丢失
别把 finally 当作守护线程的清理入口
由于执行不可靠,以下做法风险极高:
立即学习“Java免费学习笔记(深入)”;
- 在守护线程的 finally 里关闭文件、释放锁、上报指标
- 依赖 finally 执行关键业务逻辑或状态持久化
- 认为“加了 finally 就算兜底”,忽略线程类型差异
真正需要可靠清理的逻辑,应放在非守护线程中,或通过 JVM shutdown hook 统一管理(注意:shutdown hook 本身也不适用于守护线程内部触发)。
System.exit 和守护线程退出本质不同
两者都会跳过 finally,但机制不一样:
- System.exit() 是主动发起进程级退出,直接终止 JVM
- 守护线程终结 是 JVM 被动收尾行为,不发中断、不抛异常、不走任何 Java 清理路径
所以这不是“执行慢没抢到”,而是 JVM 根本没给机会——线程状态瞬间变为 TERMINATED,代码行号都还没走到 finally。


















