在Java中捕获SIGINT

在没有使用JNI的情况下在java中捕获kill信号的最好方法是什么? 我确实发现了sun.misc.Signal和sun.misc.SignalHandler,并警告在未来版本中可能会被删除。

将使用JNI调用ac lib是我唯一的select?

处理这个问题的方法是注册一个closures钩子。 如果使用( SIGINT ), kill -2将导致程序正常退出并运行closures挂钩。

注册一个新的虚拟机closures挂钩。

Java虚拟机响应两种事件closures:

  • 程序正常退出,最后一个非守护进程线程退出或退出(等效于System.exit)方法被调用时,或

  • 响应用户中断(例如键入^ C)或系统范围的事件(如用户注销或系统closures)而终止虚拟机。

我在OSX 10.6.3上试了下面的testing程序,并在kill -9没有运行shutdown hook,没想到会这样。 在kill -15它每次都运行closures钩子。

 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中的closures钩子。 需要警告的是, com.sun.misc软件包是不受支持的,可能会随时更改或消失,可能只存在于Sun JVM中。

看看集成信号和exception处理描述的HotSpot JVM的能力做信号链接。 它确实涉及一些C级别的欺骗。

不会java.lang.Runtime.addShutdownHook(Thread)足够你的目的? 这些钩子在终止时由JVM运行,包括接收SIGINT ,只要JVM能够执行它们。

由于至lessJava 6,HotSpot java命令有一个-Xrs标志来禁用JVM信号处理程序。

如果使用它,则需要实现自己的SIGINTSIGTERMSIGHUPSIGQUIT处理程序,包括显式调用System.exit()

注意:这意味着当存在-Xrs标志时,SIGQUIT的线程转储设施被禁用。

请参阅https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABHDABI (也可在Windows和Solaris java对应版本上find)。