在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信号处理程序。
如果使用它,则需要实现自己的SIGINT
, SIGTERM
, SIGHUP
和SIGQUIT
处理程序,包括显式调用System.exit()
。
注意:这意味着当存在-Xrs
标志时,SIGQUIT的线程转储设施被禁用。
请参阅https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABHDABI (也可在Windows和Solaris java
对应版本上find)。