Java 简明教程

Java - JVM Shutdown Hook

JVM Shutdown

以下是 JVM 关闭的两种不同方式:

  1. A controlled process:如果调用 System.exit() method 、按下 CTRL+C 或最后一个非守护线程终止,则 JVM 就会启动关闭进程。

  2. An abrupt manner:如果 JVM 接收 kill 信号,调用 Runtime.getRuntime().halt() method 或发生任何类型的 OS 恐慌,则 JVM 就会启动关闭进程。

JVM Shutdown Hook

关闭钩子只是一个已初始化但尚未启动的线程。当虚拟机开始其关闭序列时,它将以某种未指定顺序启动所有已注册的关闭钩子,并让它们并发运行。当所有钩子都完成后,它将运行所有未调用的终结器(如果启用了退出时的终结)。最后,虚拟机将停止。请注意,在关闭序列期间,守护线程将继续运行,如果通过调用退出方法启动关闭,则非守护线程也将继续运行。

JVM Shutdown Hook: The addShutdownHook(Thread hook) Method

Runtime addShutdownHook(Thread hook) method 注册新的虚拟机关机挂钩。

Declaration

以下是对 java.lang.Runtime.addShutdownHook() 方法的声明

public void addShutdownHook(Thread hook)

Parameters

hook − 已初始化但尚未启动的 Thread 对象。

Return Value

此方法不返回值。

Exception

  1. IllegalArgumentException − 如果已经注册了指定的钩子,或者如果可以确定该钩子已经运行或已经运行完。

  2. IllegalStateException − 如果虚拟机已经处于关闭过程中。

  3. SecurityException − 如果存在安全管理器,并且它拒绝 RuntimePermission("shutdownHooks")。

Example of JVM Shutdown Hook

在此示例中,我们通过扩展 Thread 类创建了一个 CustomThread 类。此线程对象将用作 JVM 关闭钩子。CustomThread 类具有 run() 方法实现。在主类 TestThread 中,我们通过使用 Runtime.getRuntime().addShutdownHook() 方法传递一个线程对象添加了一个关闭钩子。您可以在输出中验证在程序即将退出时调用 CustomThread run() 方法。

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() 方法。

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() 方法删除该钩子。

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...