在 Java 中捕获 SIGINT

2022-09-01 00:59:52

在java中捕获终止信号的最佳方法是什么,而无需使用JNI。我确实发现了sun.misc.Signal和sun.misc.SignalHandler,以及在未来版本中可能被删除的警告。

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


答案 1

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

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

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

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

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

我在OSX 10.6.3上尝试了以下测试程序,并且没有运行关机钩子,没有想到它会。在它上它每次都会运行关闭钩子。kill -9kill -15

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中不是关闭钩子。请注意,软件包 和 不受支持,可能随时更改或消失,并且可能只存在于 Sun JVM 中。com.sun.misc


答案 2

至少从Java 6开始,HotSpot命令就有一个标志来禁用JVM信号处理程序。java-Xrs

如果使用它,则需要实现自己的 、 和 处理程序,包括一个显式调用 的处理程序。SIGINTSIGTERMSIGHUPSIGQUITSystem.exit()

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

请参见 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BABHDABI(在 Windows 和 Solaris 对应产品上也可用)。java


推荐