Поведение по умолчанию задокументировано в Runtime # addShutdownHook :
В редких случаях виртуальная машина может прерваться, то есть прекратить работу, не выключившись полностью.Это происходит, когда виртуальная машина завершается извне, например, с помощью сигнала SIGKILL в Unix или вызова TerminateProcess в Microsoft Windows.Виртуальная машина также может прервать работу, если собственный метод не работает, например, из-за повреждения внутренних структур данных или попытки доступа к несуществующей памяти.Если виртуальная машина прерывает работу, то нельзя гарантировать, будут ли запущены какие-либо перехватчики завершения работы.
Чтобы обойти это поведение и отправить прерывание на сигналы уничтожения, вы можете сделать что-то похожее на это.:
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)
будет напечатано при получении сигнала уничтожения.