用Java捕获SIGINT

时间:2010-03-29 21:42:15

标签: java signals

在不使用JNI的情况下捕获java中的kill信号的最佳方法是什么。我确实发现了sun.misc.Signal和sun.misc.SignalHandler以及在将来的版本中被删除的可能性的警告。

使用JNI调用c lib是我唯一的选择吗?

3 个答案:

答案 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信号处理程序。

如果您使用它,则需要实施自己的SIGINTSIGTERMSIGHUPSIGQUIT处理程序,包括一个明确调用System.exit()的处理程序

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

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