Ezio's Blog
Posts Categories Tags Music Mood About
Ezio's Blog· Light
☰ Menu
Posts Categories Tags Music Mood About
Expand all Back to top Go to bottom

Java-Shutdown Hook

Author: Ezio Date: October 28, 2022  10:26:53 Category: Java

什么是 Shutdown Hook

Shutdown Hook 是一种比较特殊的结构,一般用于在 JVM 关闭之前,需要执行的一些操作的时候。常见的,比如说你的程序退出时需要做一些清理工作的时候,就可以考虑使用Shutdown Hook。但是如果你的JVM是非正常退出的,比如接收了SIGKILL,这个时候就不能保证shutdown hook能够正常执行。

使用方法

在java程序中,可以通过添加关闭钩子函数,实现在程序退出时关闭资源、平滑退出的功能。

JVM自带的shutdownHook

特点: jvm自带,使用方便,多个钩子间是并行执行的

主要就是通过 Runtime.addShutDownHook(Thread hook) 来实现的。下面我们来简单看一个示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ShutDownHookTest
{
public static void main(String[] args)
{

Runtime.getRuntime().addShutdownHook(new Thread()
{
public void run()
{
System.out.println("Shutdown Hook now");
}
});
System.out.println("exit");
}
}

监听 Spring 的 ContextClosedEvent

以下是 Spring 官网的对于 ContextClosedEvent 的描述

实现ApplicationListener接口,监听ContextClosedEvent

1
2
3
4
5
6
7
8
@Component
@Slf4j
public class ShutdownHookDemo implements ApplicationListener<ContextClosedEvent> {
@Override
public void onApplicationEvent(ContextClosedEvent event) {
log.info("shutdown hook, ContextClosedEvent");
}
}

实现 DisposableBean 接口

1
2
3
4
5
6
7
8
@Component
@Slf4j
public class ShutdownHookDemo implements DisposableBean {
@Override
public void destroy() throws Exception {
log.info("shutdown hook, disposable bean");
}
}

使用注解@PreDestory

1
2
3
4
5
6
7
8
@Component
@Slf4j
public class ShutdownHookDemo {
@PreDestroy
public void preDestroy() {
log.info("shutdown hook, pre destroy");
}
}

应用场景

  • 程序正常退出

  • 程序出现异常

  • 使用 System.exit()

  • 终端使用 Ctrl+C 触发的中断

  • 系统关闭

  • OutofMemory宕机

  • 使用 Kill pid 杀死进程(使用kill -9是不会被调用的)

JVM Shutdown Hook 注意事项

  • Shutdown Hook不能保证一定执行
    如果JVM crashe了, Shutdown Hook并不能保证一定执行。例如如果收到了SIGKILL的时候,程序会立刻终止执行,JVM立刻退出,导致没有机会执行Shutdown Hook.如果调用了Runtime.halt()的情况下,也可以导致JVM在没有执行Shutdown Hook的时候直接退出。当然,如果一个程序正常结束,会在JVM退出去调用Shutdown Hook。如果JVM因为用户要求中断或者是接受到SIGTERM,也是会调用Shutdown Hook的。

  • Shutdown Hook是可以被强制中断的
    即使已经开始执行Shutdown Hook,也是可以被中断的,比如当接收到了SIGTERM,但是shutdown hook没有在一定时间内完成,也是会被强制中断,导致shutdown hook没有完整执行。所以一般在Shutdown hook中的操作都应该是可以快速执行完毕,不应该是一些long time的任务。

  • Shutdown Hook可以有多个
    一个程序中可以注册多个shutdown hook,但是JVM执行shutdown hook的时候是一个任意顺序,并且JVM执行hook的时候是并发的。

  • Shutdown hook中不可以regist/unregister shutdown hook
    如果这么做了,JVM会抛IllegalStateException。

  • Shutdown hook可以被停止
    如果一个Shutdown已经开始执行了,除了例如SIGKILL这样的外部干预,需要且只能通过Runtime.halt()中断。

  • Shutdown hook需要安全权限

Author: Ezio

Permalink: https://ezioy.cn/2022/10/28/Java-Shutdown-Hook/

License: Copyright (c) 2019 CC-BY-NC-4.0 LICENSE

Slogan: Nothing is true,Everything is permitted

Tag(s): # Java
back · home
Linux Kill命令 Spring Validation
Ezio © 2019 - 2026 | Powered by Hexo & Chic | 访客数量:   浏览次数: | 渝公网安备50011302222043 | 渝ICP备2023013933号-1