将关闭挂钩设置为非守护进程

时间:2012-08-21 14:23:08

标签: java multithreading shutdown

当我的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);

在此示例中,关闭过程一直计算到最后没有问题。 (所以没有重新组合)

如何在我的应用中修复它?
我该如何重建它?

2 个答案:

答案 0 :(得分: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将立即退出。

答案 1 :(得分:1)

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