问题 CTRL-C如何与Java程序一起使用


当我按下 CTRL - C 在控制台中,应用程序线程停止和关闭钩子的调用顺序是什么?


4001
2017-07-11 14:59


起源

引用文档:当虚拟机开始其关闭序列时,它将以某种未指定的顺序启动所有已注册的关闭挂钩,并让它们同时运行。当所有钩子都完成后,如果启用了终止退出,它将运行所有未被发送的终结器。 因此我们可以收集关闭钩子总是先被调用,这是有道理的,或者如果线程被关闭,那么这样的钩子会是什么意思?告诉用户他的数据已经消失 - David Kroukamp


答案:


根据javadocs,注册的关闭钩子被调用 不明 JVM开始关闭时的顺序;例如响应CTRL-C。

应用程序线程不会以任何明确定义的方式“停止”。实际上,他们可以继续正常运行,直到流程退出。

如果您希望以有序的方式关闭线程,则需要在关闭钩子中执行某些操作以使其发生。例如,关闭挂钩可以调用 Thread.interrupt() 告诉工作者线程停止他们正在做什么......并打电话 join() 确保它已经发生。


8
2017-07-11 16:03



警告; Thread.join() 在关闭期间等待不遵守中断的线程会导致死锁。这是一个好主意 Thread.join(long) 具有合理的超时以确保行为不当的线程不会阻止进程退出。 - dimo414
好点子。但是,如果您确实有一个对中断没有正确响应的线程,并且无论如何拔出JVM上的插件,那么存在可能会丢失某些内容的风险。所以,IMO,更好的方法是找到并解决“死锁”的原因;即更改违规线程以正确处理中断。 - Stephen C


我知道您可以通过添加关闭钩子来指定在击中Ctrl-C时应该发生什么。但我不确定它的顺序。

private static void createShutDownHook()
{
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable()
    {

        @Override
        public void run()
        {
            System.out.println();
            System.out.println("Thanks for using the application");
            System.out.println("Exiting...");

        }
    }));
}

5
2017-07-11 15:01