如何在Java中最好地捕获kill信号而不使用JNI。我发现了sun.misc.Signal和sun.misc.SignalHandler,但警告未来版本可能会删除它们。
那么,我唯一的选择是使用JNI调用C库吗?
kill -2
将导致程序优雅地退出并运行关闭钩子。
注册新的虚拟机关机挂钩。
Java虚拟机响应两种类型的事件而关闭:
程序正常退出,当最后一个非守护线程退出或调用exit(等效于System.exit)方法时,或者
虚拟机响应用户中断(例如键入^C)或系统范围事件(例如用户注销或系统关闭)而终止。
我在OSX 10.6.3上尝试了以下测试程序,在kill -9
上它没有运行关闭钩子,我认为它不会。在kill -15
上,它每次都会运行关闭钩子。
public class TestShutdownHook
{
public static void main(final String[] args) throws InterruptedException
{
Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
System.out.println("Shutdown hook ran!");
}
});
while (true)
{
Thread.sleep(1000);
}
}
}
这是编写自己的 Java 信号处理程序 的记录方式,而不是关闭钩子。请注意,com.sun.misc
包是不受支持的,可能会在任何时候更改或消失,并且很可能只存在于 Sun JVM 中。
SIGKILL
(9)是一个不可被捕获的信号,这是 Unix 设计的一个特性。 - dolmencom.sun
包。 - user177800SIGKILL(9)
会导致虚拟机中止,根据文档:
如果虚拟机中止,则不能保证是否会运行任何关闭挂钩。
http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook%28java.lang.Thread%29 - adinocom.sun.*
类是可用且维护的,不像sun.*
类(请注意com.
前缀)。 - Matthieujava
命令就有一个-Xrs
标志,用于禁用JVM信号处理程序。SIGINT
、SIGTERM
、SIGHUP
和SIGQUIT
处理程序,包括一个显式调用System.exit()
的处理程序。-Xrs
标志时,SIGQUIT的线程转储功能将被禁用。java
对应项)。java.lang.Runtime.addShutdownHook(Thread)
?只要JVM能够执行它们,这些挂钩将在终止时(包括接收到SIGINT
)由JVM运行。