在不使用JNI的情况下捕获java中的kill信号的最佳方法是什么。我确实发现了sun.misc.Signal和sun.misc.SignalHandler以及在将来的版本中被删除的可能性的警告。
使用JNI调用c lib是我唯一的选择吗?
答案 0 :(得分:54)
处理此问题的方法是注册shutdown挂钩。如果使用( SIGINT )kill -2
将导致程序正常退出并运行关闭挂钩。
注册新的虚拟机 关机钩。
Java虚拟机关闭了 回应两种事件:
当最后一个非守护程序线程退出或调用exit(等效,System.exit)方法时,程序正常退出,或者
虚拟机将响应用户中断(例如键入^ C)或系统范围的事件(例如用户注销或系统关闭)而终止。
我在OSX 10.6.3和kill -9
上尝试了以下测试程序, NOT 运行了关闭钩子,不认为会这样。在kill -15
上 DOES 每次都会运行关闭挂钩。
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);
}
}
}
这是编写自己的signal handlers的文档化方法,它不是Java中的关闭挂钩。是warned com.sun.misc
包并且不受支持,可能随时更改或消失,可能只存在于Sun JVM中。
答案 1 :(得分:4)
看看Integrating Signal and Exception Handling描述HotSpot JVM执行信号链接的能力。它确实涉及一些C级技巧。
java.lang.Runtime.addShutdownHook(Thread)
不能满足您的目的吗?这些挂钩在终止时由JVM运行,包括接收SIGINT
,只要JVM能够执行它们。
答案 2 :(得分:4)
至少从Java 6开始,HotSpot java
命令有一个-Xrs
标志来禁用JVM信号处理程序。
如果您使用它,则需要实施自己的SIGINT
,SIGTERM
,SIGHUP
和SIGQUIT
处理程序,包括一个明确调用System.exit()
的处理程序
注意:这意味着当-Xrs
标志存在时,SIGQUIT的线程转储功能被禁用。
请参阅https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABHDABI(也可在Windows和Solaris java
对应网站上找到)。