6

是无操作吗?JVM 是否避免再次调用关闭挂钩?

对于一个用例,考虑一个 UncaughtExceptionHandler,它为 SomeException 调用 System.exit(),然后在短时间内将 SomeException 抛出到两个单独的线程中。

此外,假设在新线程中调用 System.exit() 以避免潜在的死锁。

更新

正如其中一条评论正确指出的那样,我应该自己测试一下,但我很懒。无论在常规线程或守护线程中调用 System.exit() 并在打印后以代码 1 退出,以下测试都成功完成:

Requesting shutdown ...
Shutdown started ...
Requesting shutdown ...
Shutdown completed ...

这是代码:

public class ConcurrentSystemExit {

  private final static boolean DAEMON = false;

  public static void main(String[] args) throws InterruptedException {

    // Register a shutdown hook that waits 6 secs
    Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() {
        try {
          System.out.println("Shutdown started ...");
          Thread.sleep(6000);
          System.out.println("Shutdown completed ...");
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    });

    // Define a Thread that calls exit()
    class ShutdownThread extends Thread {
      public void run() {
        System.out.println("Requesting shutdown ...");
        System.exit(1);
      }
    }

    // Issue first exit()
    Thread t1 = new ShutdownThread();
    t1.setDaemon(DAEMON);
    t1.start();

    Thread.sleep(3000);

    // Issue second exit()
    Thread t2 = new ShutdownThread();
    t2.setDaemon(DAEMON);
    t2.start();
  }
}
4

2 回答 2

5

JavaDoc开始Runtime.exit()

如果在虚拟机开始其关闭序列之后调用此方法,则如果正在运行关闭挂钩,则此方法将无限期阻塞。如果已经运行了关闭挂钩并且已启用退出终止,则此方法会在状态非零时使用给定的状态代码暂停虚拟机;否则,它会无限期地阻塞。

于 2013-11-05T20:42:44.480 回答
0

仅供参考,exit() 方法可以抛出 SecurityException。

抛出:SecurityException - 如果存在安全管理器并且其 checkExit 方法不允许以指定状态退出。

系统(Java 平台 SE 7)

如果在 JVM 关闭过程中再次调用 System.exit() 会发生什么?

这取决于安全上下文,但在大多数情况下,调用 exit 方法后什么都不执行,它只是终止 JVM。

于 2013-11-05T20:57:03.743 回答