运行时 addShutdownHook(Thread hook) 方法注册一个新的虚拟机关闭挂钩。 Java 虚拟机响应两种事件而关闭。
程序正常退出,当最后一个非守护线程退出时或退出 (等效地,调用 System.exit) 方法,或者
虚拟机因响应用户中断而终止,例如键入 ^C 或系统范围的事件,例如用户注销或系统关闭。
关闭挂钩只是一个已初始化但未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。当所有挂钩完成后,如果启用了退出时终结,它将运行所有未调用的终结器。最后,虚拟机将停止。请注意,守护线程将在关闭序列期间继续运行,如果通过调用 exit 方法启动关闭,则非守护线程也会继续运行。
声明
以下是 java.lang.Runtime.addShutdownHook() 方法
public void addShutdownHook(Thread hook)
参数
hook - 已初始化但未启动的 Thread 对象。
返回值
此方法不返回值。
异常
IllegalArgumentException - 如果指定的钩子已经注册,或者可以确定该钩子已经运行或已经运行。
IllegalStateException - 如果虚拟机已处于关闭过程中。
SecurityException - 如果存在安全管理器并且它拒绝 RuntimePermission("shutdownHooks")。
示例 1
在此示例中,我们通过扩展 Thread 类来创建一个 CustomThread 类。该线程对象将用作 JVM 关闭挂钩。 CustomThread 类具有 run() 方法实现。在主类 TestThread 中,我们通过向其传递一个线程对象,使用 Runtime.getRuntime().addShutdownHook() 方法添加了一个关闭钩子。在输出中,您可以验证当程序即将退出时是否调用了 CustomThread run() 方法。
package com.yxjc123;
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 {
// 将 CustomThread 注册为关闭钩子
Runtime.getRuntime().addShutdownHook(new CustomThread());
//打印程序的状态
System.out.println("Program is starting...");
//导致线程休眠3秒
System.out.println("Waiting for 3 seconds...");
Thread.sleep(3000);
//打印程序正在关闭
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.
示例 2
在此示例中,我们通过实现 Runnable 接口来创建一个 CustomThread 类。该线程对象将用作 JVM 关闭挂钩。 CustomThread 类具有 run() 方法实现。在主类 TestThread 中,我们通过向其传递一个线程对象,使用 Runtime.getRuntime().addShutdownHook() 方法添加了一个关闭钩子。在输出中,您可以验证当程序即将退出时是否调用了 CustomThread run() 方法。
package com.yxjc123;
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 {
//将CustomThread注册为关闭钩子
Runtime.getRuntime().addShutdownHook(new Thread(new CustomThread()));
//打印程序的状态
System.out.println("Program is starting...");
//导致线程休眠3秒
System.out.println("Waiting for 3 seconds...");
Thread.sleep(3000);
//打印程序正在关闭
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.
示例 3
我们可以删除关闭钩子也可以使用removeShutdownHook()。在此示例中,我们通过实现 Runnable 接口创建一个 CustomThread 类。该线程对象将用作 JVM 关闭挂钩。 CustomThread 类具有 run() 方法实现。在主类 TestThread 中,我们通过向其传递一个线程对象,使用 Runtime.getRuntime().addShutdownHook() 方法添加了一个关闭钩子。作为最后一条语句,我们使用 Runtime.getRuntime().removeShutdownHook() 方法删除钩子
package com.yxjc123;
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());
//将消息注册为关闭钩子
Runtime.getRuntime().addShutdownHook(hook);
//打印程序的状态
System.out.println("Program is starting...");
//导致线程休眠3秒
System.out.println("Waiting for 3 seconds...");
Thread.sleep(3000);
//打印程序正在关闭
System.out.println("Program is closing...");
Runtime.getRuntime().removeShutdownHook(hook);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output
Program is starting...
Waiting for 3 seconds...
Program is closing...