Java中的System.exit()和Runtime.getRuntime().halt()


1. System.exit()
 
System.exit()方法,停止正在运行的Java虚拟机。但是,在停止JVM之前,它将调用关闭序列,也称为有序关闭。

 
JVM的关闭序列首先调用所有已注册的关闭挂钩,并等待它们完成。然后,如果启用了退出完成,它将运行所有未调用的终结器。最后,它停止了JVM。

实际上,此方法在内部调用Runtime.getRuntime().exit()方法。它以整数状态码作为参数,并具有void返回类型:

public static void exit(int status)
如果状态码不为零,则表明程序异常停止。

2. Runtime.getRuntime().halt()
 
在运行时类允许在该应用程序运行环境的应用程序进行交互。

它有一个halt方法,可用于强制终止正在运行的JVM。

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

此方法是非静态的,并且具有与System.exit()类似的签名 :

public void halt(int status)
与exit相似,此方法中的非零状态代码也表示程序异常终止。

3.例子
 
现在,让我们在关闭钩子的帮助下看一个退出和暂停方法的例子。

 
 
 
为简单起见,我们将创建一个Java类并在静态块中注册一个关闭钩子。另外,我们将创建两个方法;第一个调用exit方法,第二个调用halt方法:

import org.apache.log4j.Logger;
 
public class JvmExitAndHaltDemo {
 
    private static Logger LOGGER = Logger.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.");
    }
 
    public static void main(String[] args) {
        JvmExitAndHaltDemo demo = new JvmExitAndHaltDemo();
        // demo.processAndExit();
        demo.processAndHalt();
    }
}
因此,首先要测试exit方法,让我们创建一个测试用例:

    public static void main(String[] args) {
        JvmExitAndHaltDemo demo = new JvmExitAndHaltDemo();
        demo.processAndExit();
    }
现在让我们运行测试用例,看看关闭钩子被称为:

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.
同样,我们将为halt方法创建一个测试用例:

    public static void main(String[] args) {
        JvmExitAndHaltDemo demo = new JvmExitAndHaltDemo();
        demo.processAndHalt();
    }
现在,我们也可以运行此测试用例,并看到未调用shutdown钩子:

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().
4.何时使用退出和停止
 
如前所述,System.exit()方法触发了JVM的关闭序列,而Runtime.getRuntime().halt()则突然终止了JVM。

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

因此,我们很少需要使用这些方法。话虽如此,当我们需要JVM运行注册的关机钩子或将特定的状态代码返回给调用方(例如使用Shell脚本)时,可能需要使用exit方法。

但是,重要的是要注意,如果设计不当,关闭挂钩可能会导致死锁。因此,退出方法可能会阻塞,直到它等待注册的关闭挂钩完成为止。因此,解决此问题的一种可行方法是在出口阻塞的情况下使用halt方法强制JVM停止。

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值