所以我有这个代码块:
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>
我希望它能显示“ Interrupted”和一个堆栈跟踪信息,但是该程序只是直接被杀死。我应该如何优雅地处理杀伤信号?
答案 0 :(得分:0)
默认行为记录在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)
在收到终止信号时被打印。