Java程序中如何使用CTRL-C?

14

当我在控制台按下ctrl-c时,应用程序线程的停止顺序和关闭钩子的调用顺序是怎样的?


2
引用文档:当虚拟机开始关闭序列时,它将按某种未指定的顺序启动所有已注册的关闭挂钩,并让它们并发运行。当所有挂钩都完成后,如果启用了退出时终结,则会运行所有未调用的终结器。 因此,我们可以得出结论,无论如何都会首先调用关闭挂钩,这是有意义的,否则如果线程首先关闭,那么这样的挂钩有什么意义呢?告诉用户他的数据已经丢失。 - David Kroukamp
2个回答

12
根据Javadoc文档,注册的关闭挂钩在JVM开始关闭时以未指定的顺序调用;例如响应CTRL-C信号。
应用程序线程没有任何明确定义的方式“停止”。事实上,它们可以一直运行直到进程退出。
如果你想让你的线程有序地关闭,你需要在关闭挂钩中做一些事情来实现。例如,一个关闭挂钩可以调用Thread.interrupt()命令工作线程停止正在进行的工作...并调用join()以确保已经发生了这种情况。

注意:Thread.join()在等待不遵守中断的线程关闭期间可能会导致死锁。建议使用Thread.join(long)设置合理的超时时间,以确保行为异常的线程不会阻塞进程退出。 - dimo414
好观点。然而,如果您有一个线程不能正确响应中断,并且无论如何都关闭JVM,那么有可能会破坏某些东西。因此,在我看来,更好的方法是找到并修复“死锁”的原因;即更改有问题的线程以正确处理中断。 - Stephen C
我可以假设这意味着除非您手动中断主线程或在关闭挂钩内尝试终止它,否则主线程不会被中断吗? - experiment unit 1998X

5

我知道可以通过添加关闭钩子(shutdown hook)来指定在按下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...");

        }
    }));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接