Java 简明教程
Java - JVM Shutdown Hook
JVM Shutdown
以下是 JVM 关闭的两种不同方式:
The following are the two different ways for JVM shutdown –
-
A controlled process: JVM starts to shut down its process if the System.exit() method is called, CTRL+C is pressed, or if the last non-daemon thread terminates.
-
An abrupt manner: JVM starts to shut down its process if it receives a kill signal, the Runtime.getRuntime().halt() method is called, or any kind of OS panic.
JVM Shutdown Hook
关闭钩子只是一个已初始化但尚未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定顺序启动所有已注册的关闭钩子,并让它们并发运行。当所有钩子都完成后,它将运行所有未调用的终结器(如果启用了退出时的终结)。最后,虚拟机将停止。请注意,在关闭序列期间,守护线程将继续运行,如果通过调用退出方法启动关闭,则非守护线程也将继续运行。
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled. Finally, the virtual machine will halt. Note that daemon threads will continue to run during the shutdown sequence, as will non-daemon threads if shutdown was initiated by invoking the exit method.
JVM Shutdown Hook: The addShutdownHook(Thread hook) Method
Runtime addShutdownHook(Thread hook) method 注册新的虚拟机关机挂钩。
The Runtime addShutdownHook(Thread hook) method registers a new virtual-machine shutdown hook.
Declaration
以下是对 java.lang.Runtime.addShutdownHook() 方法的声明
Following is the declaration for java.lang.Runtime.addShutdownHook() method
public void addShutdownHook(Thread hook)
Exception
-
IllegalArgumentException − If the specified hook has already been registered, or if it can be determined that the hook is already running or has already been run.
-
IllegalStateException − If the virtual machine is already in the process of shutting down.
-
SecurityException − If a security manager is present and it denies RuntimePermission("shutdownHooks").
Example of JVM Shutdown Hook
在此示例中,我们通过扩展 Thread 类创建了一个 CustomThread 类。此线程对象将用作 JVM 关闭钩子。CustomThread 类具有 run() 方法实现。在主类 TestThread 中,我们通过使用 Runtime.getRuntime().addShutdownHook() 方法传递一个线程对象添加了一个关闭钩子。您可以在输出中验证在程序即将退出时调用 CustomThread run() 方法。
In this example, we’re creating a class CustomThread by extending Thread class. This thread object will be used as JVM Shutdown hook. CustomThread class has run() method implementation. In main class TestThread, we’ve added a shutdown hook using Runtime.getRuntime().addShutdownHook() method, by passing it a thread object. In output you can verify that CustomThread run() method is called when program is about to exit.
package com.tutorialspoint;
class CustomThread extends Thread {
public void run() {
System.out.println("JVM is shutting down.");
}
}
public class TestThread {
public static void main(String args[]) throws InterruptedException {
try {
// register CustomThread as shutdown hook
Runtime.getRuntime().addShutdownHook(new CustomThread());
// print the state of the program
System.out.println("Program is starting...");
// cause thread to sleep for 3 seconds
System.out.println("Waiting for 3 seconds...");
Thread.sleep(3000);
// print that the program is closing
System.out.println("Program is closing...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Program is starting...
Waiting for 3 seconds...
Program is closing...
JVM is shutting down.
More Example of JVM Shutdown Hook
Example 1
在此示例中,我们通过实现 Runnable 接口创建了一个 CustomThread 类。此线程对象将用作 JVM 关闭钩子。CustomThread 类具有 run() 方法实现。在主类 TestThread 中,我们通过使用 Runtime.getRuntime().addShutdownHook() 方法传递一个线程对象添加了一个关闭钩子。您可以在输出中验证在程序即将退出时调用 CustomThread run() 方法。
In this example, we’re creating a class CustomThread by implementing Runnable interface. This thread object will be used as JVM Shutdown hook. CustomThread class has run() method implementation. In main class TestThread, we’ve added a shutdown hook using Runtime.getRuntime().addShutdownHook() method, by passing it a thread object. In output you can verify that CustomThread run() method is called when program is about to exit.
package com.tutorialspoint;
class CustomThread implements Runnable {
public void run() {
System.out.println("JVM is shutting down.");
}
}
public class TestThread {
public static void main(String args[]) throws InterruptedException {
try {
// register CustomThread as shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread(new CustomThread()));
// print the state of the program
System.out.println("Program is starting...");
// cause thread to sleep for 3 seconds
System.out.println("Waiting for 3 seconds...");
Thread.sleep(3000);
// print that the program is closing
System.out.println("Program is closing...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Program is starting...
Waiting for 3 seconds...
Program is closing...
JVM is shutting down.
Example 2
我们也可以使用 removeShutdownHook() 删除关闭钩子。在此示例中,我们通过实现 Runnable 接口创建了一个 CustomThread 类。此线程对象将用作 JVM 关闭钩子。CustomThread 类具有 run() 方法实现。在主类 TestThread 中,我们通过使用 Runtime.getRuntime().addShutdownHook() 方法传递一个线程对象添加了一个关闭钩子。作为最后一条语句,我们将使用 Runtime.getRuntime().removeShutdownHook() 方法删除该钩子。
We can remove the shutdown hook as well using removeShutdownHook(). In this example, we’re creating a class CustomThread by implementing Runnable interface. This thread object will be used as JVM Shutdown hook. CustomThread class has run() method implementation. In main class TestThread, we’ve added a shutdown hook using Runtime.getRuntime().addShutdownHook() method, by passing it a thread object. As last statement, we’re removing the hook using Runtime.getRuntime().removeShutdownHook() method
package com.tutorialspoint;
class CustomThread implements Runnable {
public void run() {
System.out.println("JVM is shutting down.");
}
}
public class TestThread {
public static void main(String args[]) throws InterruptedException {
try {
Thread hook = new Thread(new CustomThread());
// register Message as shutdown hook
Runtime.getRuntime().addShutdownHook(hook);
// print the state of the program
System.out.println("Program is starting...");
// cause thread to sleep for 3 seconds
System.out.println("Waiting for 3 seconds...");
Thread.sleep(3000);
// print that the program is closing
System.out.println("Program is closing...");
Runtime.getRuntime().removeShutdownHook(hook);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Program is starting...
Waiting for 3 seconds...
Program is closing...