JVM关闭序列与事务管理:Spring Boot触发关闭时运行中方法执行规则问询
JVM关闭流程及Spring Boot Shutdown Actuator触发后的执行逻辑
核心结论
两种情况都有可能,完全取决于你是否开启了Spring Boot的优雅关机配置,以及methodA()运行所在的线程类型。
1. 未开启优雅关机(Spring Boot 默认配置)的情况
- 此时触发shutdown actuator后,Spring上下文会直接关闭,销毁所有Bean,随后触发JVM关闭钩子,不会等待用户业务线程执行完成
- 你提到的
methodA()如果是普通的业务请求线程,会被直接中断,大概率执行到250行就停止,对应你说的第二种情况 - 特殊说明:如果
methodA()内部捕获了InterruptedException且没有重新抛出,也没有响应中断信号,那这段代码会继续执行到结束,但此时Spring上下文已经销毁,依赖注入的Bean可能已经不可用,会抛出各类运行时异常。
2. 开启优雅关机后的情况
Spring Boot 2.3+ 提供了原生优雅关机能力,开启方式是在配置文件添加:
server.shutdown=graceful spring.lifecycle.timeout-per-shutdown-phase=30s
- 开启后触发关闭流程时,Spring Boot会先停止接收新请求,然后给已有的业务线程留出配置的缓冲时间(上方示例配置为30秒)等待执行完成
- 只要
methodA()剩余的250行代码能在缓冲时间内执行完,就会完整跑完所有逻辑后再推进关闭流程,对应你说的第一种情况 - 如果
methodA()执行时间超过缓冲时间,还是会被强制中断,提前终止。
特殊线程场景说明
如果methodA()是运行在守护线程上,不管有没有开启优雅关机,只要JVM的所有非守护线程执行完成,守护线程会被直接终止,不会等待方法执行完成。
JVM标准固定关闭流程
JVM存在明确的固定关闭流程,只有强制关闭场景才会直接终止程序:
- 正常关闭触发(通过
System.exit()、kill -15信号、Spring Shutdown Actuator等方式)时,执行顺序为:- 执行所有已注册的
ShutdownHook线程,Spring的关闭逻辑就是注册在该阶段的钩子 - 调用所有未被调用的finalize方法(该特性已被JDK标记废弃)
- 终止JVM进程
- 执行所有已注册的
- 强制关闭触发(kill -9信号、操作系统直接杀死进程、JVM crash)时,会直接终止程序,不走上述流程。
内容的提问来源于stack exchange,提问作者user1354825
相关产品推荐
相关产品推荐

