结束JVM的方法,System.exit(int status)和Runtime类中的halt(int status)

很多时候我们需要提前关闭JVM已结束程序的运行,比如用户不按规则操作的时候,比如try-catch接收到异常的时候我们就需要提前结束程序,结束java程序就是关闭java虚拟机JVM。

那么,我们常用的方法就是

System.exit(0);

这句语句的意思就是终止当前运行的java虚拟机,参数是作为状态码,通常非0代表非正常退出。
在文档中找到这个方法的描述是: 该方法调用 Runtime 类中的 exit 方法。该方法永远不会正常返回。

看其实现代码也的确是调用了Runtime的方法

public static void exit(int status) {
        Runtime.getRuntime().exit(status);
}

那么问题来了,该方法的描述是:
通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。此方法从不正常返回。可以将变量作为一个状态码;根据惯例,非零的状态码表示非正常终止。
虚拟机的关闭序列包含两个阶段。在第一个阶段中,会以某种未指定的顺序启动所有已注册的关闭钩子 (hook)(如果有的话),并且允许它们同时运行直至结束。在第二个阶段中,如果已启用退出终结,则运行所有未调用的终结方法。一旦完成这个阶段,虚拟机就会暂停。
如果在虚拟机已开始其关闭序列后才调用此方法,那么若正在运行关闭钩子,则将无限期地阻断此方法。如果已经运行完关闭钩子,并且已启用退出终结 (on-exit finalization),那么此方法将利用给定的状态码(如果状态码是非零值)暂停虚拟机;否则将无限期地阻断虚拟机。

表示调用该方法可能存在无法结束JVM的情况,百度了一下,也的确有人反应曾经出现无法结束进程的BUG,其实就是这个方法的原因。就像Windows关机那样,如果有进程阻止关机那么就无法立刻关机。

于是乎我翻翻翻到了Runtime类中去,找到了这个方法:
——–void halt(int status)
———– 强行终止目前正在运行的 Java 虚拟机。
方法说明中指明,该方法要慎用,因为它会无条件的结束当前虚拟机。
—–应小心使用此方法。与 exit 方法不同,此方法不会启动关闭钩子,并且如果已启用退出终结,此方法也不会运行未调用的终结方法。如果已经发起关闭序列,那么此方法不会等待所有正在运行的关闭钩子或终结方法完成其工作。

就如同Windows关机,不等待程序保存未保存的信息直接强行关机,可能会导致一些必要的的数据来不及处理产生不想看到的结果。

猜你喜欢

转载自blog.csdn.net/yzccc/article/details/53731228