【问题标题】:Why doesn't the main thread run to completion when java receives a kill signal?java收到kill信号后,为什么主线程没有运行完成?
【发布时间】:2019-01-21 13:03:31
【问题描述】:

所以我有这个代码块:

package com.stackoverflow.jontejj.killsignal;
public class Problem {
    public static void main(String[] args) {
        try {
            System.out.println("Executing");
            Thread.sleep(1000000);
            System.out.println("Done sleeping");
        } catch (InterruptedException e) {
            System.out.println("Interrupted");
            throw new RuntimeException(e);
        }
        System.out.println("Finished");
    }

}

我正在尝试使用

中止主要方法
    kill -15 <pid>

我希望它打印“中断”和堆栈跟踪,但程序只是直接被杀死。我应该如何优雅地处理终止信号?

【问题讨论】:

    标签: java interrupt kill-process


    【解决方案1】:

    默认行为记录在Runtime#addShutdownHook

    在极少数情况下,虚拟机可能会中止,即停止运行而不完全关闭。当虚拟机在外部终止时会发生这种情况,例如在 Unix 上使用 SIGKILL 信号或在 Microsoft Windows 上使用 TerminateProcess 调用。如果本地方法出错,例如破坏内部数据结构或尝试访问不存在的内存,虚拟机也可能中止。如果虚拟机中止,则无法保证是否会运行任何关闭挂钩。

    要解决此问题并在终止信号上发送中断,您可以执行类似于此的操作:

    package com.stackoverflow.jontejj.killsignal;
    public class Solution {
        public static void main(String[] args) {
            Thread main = Thread.currentThread();
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                try {
                    main.interrupt();
                    main.join(); //Possibly with a timeout here
                } catch (InterruptedException e1) {
                    Thread.currentThread().interrupt();
                }
            }));
            try {
                Thread.sleep(1000000);
                System.out.println("Done sleeping");
            } catch (InterruptedException e) {
                System.out.println("Interrupted");
                throw new RuntimeException(e);
            }
            System.out.println("Bye");
        }
    }
    

    这将导致:

    Interrupted
    Exception in thread "main" java.lang.RuntimeException: java.lang.InterruptedException: sleep interrupted
        at java_stopping/com.stackoverflow.jontejj.killsignal.Solution.main(Solution.java:18)
    Caused by: java.lang.InterruptedException: sleep interrupted
        at java.base/java.lang.Thread.sleep(Native Method)
        at java_stopping/com.stackoverflow.jontejj.killsignal.Solution.main(Solution.java:14)
    

    在收到终止信号时打印。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-12
      • 2011-11-24
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多