为JVM应用程序添加关机挂钩
最后修改:2020年7月12日
1.概述
它通常很容易启动服务。但是,有时我们需要计划优雅地关闭一个计划。
在本教程中,我们将以不同的方式查看JVM应用程序可以终止。然后,我们将使用Java API来管理JVM Shutdown挂钩。请请参阅本文要了解有关在Java应用程序金宝搏官网188be中关闭JVM的更多信息。
2. JVM关闭
JVM可以用两种方式关闭:
- 一个受控的过程
- 突然的态度
受控过程在其中关闭JVM时:
- 最后一个非守护进程线程终止。例如,当主线程退出时,JVM启动其关闭过程
- 从OS发送中断信号。例如,通过按Ctrl + C或记录OS
- 打电话system.exit()来自Java Code.
虽然我们都争取优雅的关机,但有时JVM可能会突然关闭和意外的方式。JVM突然关闭时关闭:
- 从OS发送杀死信号。例如,通过发出akill -9
- 打电话runtime.getRuntime()。halt()来自Java Code.
- 主机OS意外地死亡,例如,在电源故障或OS恐慌中
3.关闭钩子
JVM允许在完成关闭之前注册函数运行。这些功能通常是释放资源或其他类似房屋保留任务的好地方。在JVM术语中,这些函数称为sHutdown钩子。
Shutdown挂钩基本上是初始化但unlarted线程。当JVM开始关闭流程时,它将以未指定的顺序启动所有已注册的钩子。运行所有钩子后,JVM将停止。
3.1。添加钩子
为了添加关闭挂钩,我们可以使用runtime.getRuntime()。addshutdownhook()方法:
线程打印=新线程(() - > system.out.println(“在关闭中间”));runtime.getRuntime()。addshutdownhook(印刷品);
在这里,我们只需在JVM关闭自身之前将某些东西打印到标准输出。如果我们关闭JVM如下:
> system.exit(129);在关机的中间
然后我们会看到钩子实际上将消息打印到标准输出。
JVM负责启动挂钩线程。因此,如果给定的钩子已经启动,Java将抛出异常:
thread longrunninghook =新线程(() - > {try {thread.sleep(300);捕获(忽略InterruptedException){}});longrunninghook.start();assertthatthownby(() - > runtime.getruntime()。addshutdownhook(longrunninghook)).isinstanceof(IllegalArgumentException.class).hasmessage(“已经运行的”挂钩“);
显然,我们也无法多次注册钩子:
线程UnfortunateHook =新线程(() - > {});runtime.getRuntime()。addshutdownhook(Unfortunatehook);asserthatthrownby(() - > runtime.getruntime()。addshutdownhook(unfortunatehook)).isinstanceof(IllegalArgumentException.class).hasmessage(以前注册的“挂钩”);
3.2。去除钩子
Java提供双人去掉在注册它之后删除特定关闭挂钩的方法:
线程willnotrun =新线程(() - > system.out.println(“不会运行!”));runtime.getRuntime()。addshutdownhook(willnotrun);asserthat(runtime.getruntime()。removeshutdownhook(willnotrun))。istrue();
这removeshutdownhook()方法退货真的当Shutdown挂钩成功删除时。
3.3。警告
JVM仅在正常终端时运行关闭挂钩。因此,当外力突然杀死JVM过程时,JVM不会有机会执行关闭挂钩。此外,从Java代码中停止JVM也将具有相同的效果:
线程haltedhook =新线程(() - > system.out.println(“突然停止”));runtime.getRuntime()。addshutdownhook(haltedhook);runtime.getRuntime()。Halt(129);
这停止方法强制终止当前运行的JVM。因此,已注册的关闭挂钩不会有机会执行。
4。结论
在本教程中,我们查看了不同方式JVM应用程序可能会终止。然后,我们使用了一些运行时API来注册和解除寄存器关闭挂钩。
像往常一样,可以使用示例代码在github上。