用Java捕获SIGINT

Beg*_*gui 38 java signals

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

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

小智 54

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

注册新的虚拟机关闭挂钩.

Java虚拟机关闭以响应两种事件:

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

  • 响应于用户中断(例如,键入^ C)或系统范围的事件(例如用户注销或系统关闭),终止虚拟机.

我试图在OSX 10.6.3以下测试程序和kill -9它没有运行关闭挂钩,没想到它会.在kill -15DOES运行关机钩每次.

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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是编写自己的信号处理程序的文档化方法,这些处理程序不是Java中的关闭挂钩.被警告com.sun.misc包并为联合国支持,并可以改变或消失在任何时候,大概只有在Sun JVM存在.

  • `SIGKILL`(9)是一个非捕获信号.这是一个Unix设计功能. (8认同)

del*_*ere 5

从至少Java 6开始,HotSpot java命令具有-Xrs用于禁用JVM信号处理程序的标志。

如果你使用它,你需要实现自己的SIGINTSIGTERMSIGHUP,和SIGQUIT处理程序,其中包括一个显式调用System.exit()

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

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