3

当我的 java 应用程序关闭时 - 我的关闭挂钩直到最后都没有完全运行。
在java doc中它提到

关闭钩子也应该快速完成它们的工作......

(请参阅文档),因为它会快速关闭应用程序。
我想尝试解决它(也许将其设置为非守护线程)

所以我首先尝试使用一个简单的应用程序来重建它。
我使用添加钩子

    Runtime.getRuntime().addShutdownHook(new Thread(){
        @Override public void run() {
            for (int i = 0; i < 1000000; i++) {
                System.out.println(i);
            }

        }
    });

我扔了一个

            System.exit(1);

在此示例中,关闭过程一直计数到结束,没有问题。(所以没有重建)

如何在我的应用程序中修复它?
我怎样才能重建它?

4

2 回答 2

3

javadoc 给出了建议。如果 JVM 出现故障,你的钩子不应该运行几分钟来做各种事情。它们旨在在程序之后进行清理。

钩子线程被启动,然后join()在它们上被调用,因此 JVM在停止之前总是等待它们完成。这是来自的代码ApplicationShutdownHooks.runHooks()

static void runHooks() {
    ...
    for (Thread hook : threads) {
        hook.start();
    }
    for (Thread hook : threads) {
        hook.join();
    }
}

这就是说,如果您调用System.exit(1);,JVM 将立即退出。

于 2012-08-21T14:27:30.530 回答
1

您是否在容器中运行您的应用程序?启动停止/关闭后,容器可能会在超时后终止 JVM。正常情况下,shutdown hook 应该全部结束,这样会延迟 JVM 的关闭时间,但在极少数情况下,虚拟机可能会中止,即在没有干净关闭的情况下停止运行。当虚拟机在外部终止时会发生这种情况,例如在 Unix 上使用 SIGKILL 信号或在 Microsoft Windows 上使用 TerminateProcess 调用。如果本地方法出错,例如破坏内部数据结构或尝试访问不存在的内存,虚拟机也可能中止。如果虚拟机中止,则无法保证是否会运行任何关闭挂钩。

于 2012-08-21T14:38:22.683 回答