Runtime.getRuntime().halt() vs System.exit() in Java – Java中Runtime.getRuntime().halt()与System.exit()的比较

最后修改: 2019年 12月 10日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’ll look into System.exit(), Runtime.getRuntime().halt(), and how these two methods compare with each other.

在本教程中,我们将研究System.exit()Runtime.getRuntime().halt(),以及这两种方法的相互比较。

2. System.exit()

2.System.exit()

The System.exit() method stops the running Java Virtual Machine. But, before stopping the JVM, it calls the shutdown sequence, also known as an orderly shutdown. Please refer to this article to learn more about adding shutdown hooks.

System.exit()方法停止运行的Java虚拟机。但是,在停止JVM之前,它调用了关机序列,也被称为有序关机。请参考这篇文章以了解有关添加关机钩子的更多信息。

The shutdown sequence of JVM first invokes all registered shutdown hooks and waits for them to complete. Then, it runs all uninvoked finalizers if finalization-on-exit is enabled. Finally, it halts the JVM.

JVM的关机序列首先调用所有注册的关机钩子,并等待它们完成。然后,如果finalization-on-exit被启用,它会运行所有未调用的终结器。最后,它停止了JVM。

This method, in fact, calls the Runtime.getRuntime().exit() method internally. It takes an integer status code as an argument and has a void return type:

事实上,这个方法在内部调用Runtime.getRuntime().exit()方法。它需要一个整数状态代码作为参数,并有一个void返回类型。

public static void exit(int status)

If the status code is nonzero, it indicates that the program stopped abnormally.

如果状态代码为非零,表明程序异常停止。

3. Runtime.getRuntime().halt()

3.Runtime.getRuntime().halt()

The Runtime class allows an application to interact with the environment in which the application is running.

Runtime类允许应用程序与应用程序运行的环境进行交互。

It has a halt method that can be used to forcibly terminate the running JVM.

它有一个halt方法,可以用来强行终止正在运行的JVM

Unlike the exit method, this method does not trigger the JVM shutdown sequence. Therefore, neither the shutdown hooks or the finalizers are executed when we call the halt method.

exit方法不同,该方法不会触发JVM关机序列。因此,当我们调用halt方法时,关机钩子或终结者都不会被执行

This method is non-static and has a similar signature to System.exit():

这个方法是非静态的,其签名与System.exit()相似。

public void halt(int status)

Similar to exit, the non-zero status code in this method also indicates abnormal termination of the program.

exit类似,该方法中的非零状态码也表示程序的非正常终止。

4. Example

4.例子

Now, let’s see an example of exit and halt methods, with the help of a shutdown hook.

现在,让我们看一个exithalt方法的例子,借助于一个关闭钩。

To keep it simple, we’ll create a Java class and register a shutdown hook in a static block. Also, we’ll create two methods; the first calls the exit method and the second calls the halt method:

为了简单起见,我们将创建一个Java类,并在一个static块中注册一个关机钩。同时,我们将创建两个方法;第一个方法调用exit方法,第二个方法调用halt方法。

public class JvmExitAndHaltDemo {

    private static Logger LOGGER = LoggerFactory.getLogger(JvmExitAndHaltDemo.class);

    static {
        Runtime.getRuntime()
          .addShutdownHook(new Thread(() -> {
            LOGGER.info("Shutdown hook initiated.");
          }));
    }

    public void processAndExit() {
        process();
        LOGGER.info("Calling System.exit().");
        System.exit(0);
    }

    public void processAndHalt() {
        process();
        LOGGER.info("Calling Runtime.getRuntime().halt().");
        Runtime.getRuntime().halt(0);
    }

    private void process() {
        LOGGER.info("Process started.");
    }

}

So, to test the exit method first, let’s create a test case:

因此,为了首先测试退出方法,让我们创建一个测试案例。

@Test
public void givenProcessComplete_whenExitCalled_thenTriggerShutdownHook() {
    jvmExitAndHaltDemo.processAndExit();
}

Let’s now run the test case and see that the shutdown hook is called:

现在让我们运行测试案例,看看关闭钩子是否被调用。

12:48:43.156 [main] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Process started.
12:48:43.159 [main] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Calling System.exit().
12:48:43.160 [Thread-0] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Shutdown hook initiated.

Similarly, we’ll create a test case for the halt method:

同样地,我们将为halt方法创建一个测试用例。

@Test
public void givenProcessComplete_whenHaltCalled_thenDoNotTriggerShutdownHook() {
    jvmExitAndHaltDemo.processAndHalt();
}

Now, we can run this test case also and see that the shutdown hook is not called:

现在,我们也可以运行这个测试案例,看到关闭钩子没有被调用。

12:49:16.839 [main] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Process started.
12:49:16.842 [main] INFO com.baeldung.exitvshalt.JvmExitAndHaltDemo - Calling Runtime.getRuntime().halt().

5. When to Use exit and halt

5.何时使用exithalt

As we’ve seen earlier, the System.exit() method triggers the shutdown sequence of JVM, whereas the Runtime.getRuntime().halt() terminates the JVM abruptly.

正如我们前面所看到的,System.exit()方法会触发JVM的关闭顺序,而Runtime.getRuntime().halt()则会突然终止JVM。

We can also do this by using operating system commands. For example, we can use SIGINT or Ctrl+C to trigger the orderly shutdown like System.exit() and SIGKILL to kill the JVM process abruptly.

我们也可以通过使用操作系统的命令来做到这一点。例如,我们可以使用SIGINT或Ctrl+C来触发有序的关闭,如System.exit()和SIGKILL来突然杀死JVM进程。

Therefore, we rarely need to use these methods. Having said that, we may need to use the exit method when we need the JVM to run the registered shutdown hooks or return a specific status code to the caller, like with a shell script.

因此,我们很少需要使用这些方法。尽管如此,当我们需要JVM运行注册的关机钩子或向调用者返回特定的状态代码时,我们可能需要使用exit方法,就像使用Shell脚本一样。

However, it is important to note that the shutdown hook may cause a deadlock, if not designed properly. Consequently, the exit method can get blocked as it waits until the registered shutdown hooks finish. So, a possible way to take care of this is to use the halt method to force JVM to halt, in case exit blocks.

然而,需要注意的是,如果设计不当,关机钩子可能会导致死锁。因此,exit方法可能会被阻塞,因为它在等待注册的关机钩子完成。因此,一个可能的方法是使用halt方法来强制JVM停止,以防exit阻塞。

Finally, an application can also restrict these methods from accidental use. Both these methods call the checkExit method of the SecurityManager class. So, to disallow the exit and halt operations, an application can create a security policy using the SecurityManager class and throw the SecurityException from the checkExit method.

最后,应用程序还可以限制这些方法的意外使用。这两个方法都调用SecurityManager类的checkExit方法。因此,为了禁止exithalt操作,应用程序可以使用SecurityManager类创建一个安全策略,并从checkExit方法抛出SecurityException

6. Conclusion

6.结语

In this tutorial, we’ve looked into the System.exit() and Runtime.getRuntime().halt() methods with the help of an example. Moreover, we’ve also talked about the usage and best practices of these methods.

在本教程中,我们通过一个例子研究了System.exit()Runtime.getRuntime().halt()方法。此外,我们还讨论了这些方法的用法和最佳实践。

As usual, the complete source code of this article is available over on Github.

像往常一样,本文的完整源代码可在Github上获取。