ShutdownHook Java优雅地停止服务

ShutdownHook是啥东西?


在Java程序中可以通过添加关闭钩子,实现在程序退出时关闭资源、平滑退出的功能。 使用Runtime.addShutdownHook(Thread hook)方法,可以注册一个JVM关闭的钩子,这个钩子可以在以下几种场景被调用: 1. 程序正常退出 2. 使用System.exit() 3. 终端使用Ctrl+C触发的中断 4. 系统关闭 5. 使用Kill pid命令干掉进程

shutdownHook是一种特殊的结构,它允许开发人员插入JVM关闭时执行的一段代码。这种情况在我们需要做特殊清理操作的情况下很有用

怎么使用?


看下Runtime中的方法

addShutdownHook

1
2
3
4
5
6
7
public void addShutdownHook(Thread hook) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("shutdownHooks"));
}
ApplicationShutdownHooks.add(hook);
}

removeShutdownHook

1
2
3
4
5
6
7
public boolean removeShutdownHook(Thread hook) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("shutdownHooks"));
}
return ApplicationShutdownHooks.remove(hook);
}

可以看到就是添加一个钩子到JVM里面去,这个钩子就是一个线程,在特定情节下会被调用。

1
2
3
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("程序结束之前最后的反抗");
}));

用法简单,但是呢开发的时候很烦,因为我使用的是IDEA来开发,然后每次Terminate程序的时候点击的IDE的终止按钮。然后百度了一下,发现大部分都是通过另外启一个线程接受在console的输入,然后调用System.exit(0)来terminate程序(IDEA或者Eclipse这样的Terminate是异常中断,调用的System.exit(1))。所以修改了一下程序如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.design.test;

import java.io.IOException;

/**
* @author zhangxingrui
* @create 2018-06-21 16:24
**/
public class Main {

public static void main(String[] args) {
System.out.println("我是主线程,说点什么好呢?");

Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.out.println("程序结束之前最后的反抗");
}));

new Thread(() -> {
System.out.println("==============IDE debug==================");
System.out.println("press ENTER to call System.exit(0) ");
System.out.println("==============IDE debug==================");
try {
System.out.println(System.in.read());
} catch (IOException e) {
e.printStackTrace();
}

System.exit(0);
}).start();
}

}

程序运行结果如下:

1
2
3
4
5
6
7
8
9
10
11

我是主线程,说点什么好呢?
==============IDE debug==================
press ENTER to call System.exit(0)
==============IDE debug==================


10
程序结束之前最后的反抗

Process finished with exit code 0

参考文章

ShutdownHook - 优雅地停止服务

zhangxingrui wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!