如何在Java中优雅地处理SIGKILL信号

如何在Java中优雅地处理SIGKILL信号,java,sigkill,Java,Sigkill,当程序收到终止信号时,如何处理清除 例如,我连接的一个应用程序希望任何第三方应用程序(我的应用程序)在注销时发送finish命令。当我的应用程序被kill-9破坏时,发送finish命令的最佳方式是什么 编辑1:无法捕获kill-9。谢谢你们纠正我的错误 编辑2:我想这种情况应该是当一个人调用justkill时,它与ctrl-c相同,对于任何语言的程序来说,处理SIGKILL都是不可能的。这样,即使程序有缺陷或恶意,也始终可以终止程序。但是SIGKILL并不是终止程序的唯一方法。另一种是使用SI

当程序收到终止信号时,如何处理清除

例如,我连接的一个应用程序希望任何第三方应用程序(我的应用程序)在注销时发送
finish
命令。当我的应用程序被
kill-9
破坏时,发送
finish
命令的最佳方式是什么

编辑1:无法捕获kill-9。谢谢你们纠正我的错误


编辑2:我想这种情况应该是当一个人调用justkill时,它与ctrl-c相同,对于任何语言的程序来说,处理SIGKILL都是不可能的。这样,即使程序有缺陷或恶意,也始终可以终止程序。但是SIGKILL并不是终止程序的唯一方法。另一种是使用SIGTERM。程序可以处理这个信号。程序应通过受控但快速的关机来处理信号。当计算机关闭时,关闭进程的最后一个阶段向每个剩余进程发送一个SIGTERM,给这些进程几秒钟的宽限期,然后向它们发送一个SIGKILL

对于任何
kill-9
对象,处理此问题的方法是注册一个钩子。如果可以使用(SIGTERM
kill-15
,关闭挂钩将工作。(SIGINT
kill-2
不会导致程序正常退出并运行关闭挂钩

注册新的虚拟机关闭挂钩

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

  • 当最后一个非守护进程线程退出或调用exit(相当于System.exit)方法时,程序正常退出,或者
  • 虚拟机在响应用户中断(如键入^C)或系统范围事件(如用户注销或系统关闭)时终止
我在OSX 10.6.3和
kill-9
上尝试了以下测试程序,它确实没有像预期的那样运行关机挂钩。在一个
kill-15上,它每次都运行关闭挂钩

public class TestShutdownHook
{
    public static void main(String[] args) throws InterruptedException
    {
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                System.out.println("Shutdown hook ran!");
            }
        });

        while (true)
        {
            Thread.sleep(1000);
        }
    }
}
在任何程序中都无法真正优雅地处理
kill-9

在极少数情况下,虚拟的 机器可能会中止,即停止 在没有完全关闭的情况下运行。 当虚拟机 例如,在外部终止 在Unix或 终止对Microsoft的进程调用 窗户

处理
kill-9
的唯一实际选择是让另一个监视程序监视您的主程序离开,或者使用包装器脚本。您可以使用shell脚本轮询
ps
命令,在列表中查找您的程序,并在程序消失时执行相应操作

#!/usr/bin/env bash

java TestShutdownHook
wait
# notify your other app that you quit
echo "TestShutdownHook quit"

任何语言的程序都不可能处理SIGKILL。这样,即使程序有缺陷或恶意,也始终可以终止程序。但是SIGKILL并不是终止程序的唯一方法。另一种是使用SIGTERM。程序可以处理这个信号。程序应通过受控但快速的关机来处理信号。当计算机关闭时,关闭进程的最后一个阶段向每个剩余进程发送一个SIGTERM,给这些进程几秒钟的宽限期,然后向它们发送一个SIGKILL

对于任何
kill-9
对象,处理此问题的方法是注册一个钩子。如果可以使用(SIGTERM
kill-15
,关闭挂钩将工作。(SIGINT
kill-2
不会导致程序正常退出并运行关闭挂钩

注册新的虚拟机关闭挂钩

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

  • 当最后一个非守护进程线程退出或调用exit(相当于System.exit)方法时,程序正常退出,或者
  • 虚拟机在响应用户中断(如键入^C)或系统范围事件(如用户注销或系统关闭)时终止
我在OSX 10.6.3和
kill-9
上尝试了以下测试程序,它确实没有像预期的那样运行关机挂钩。在一个
kill-15上,它每次都运行关闭挂钩

public class TestShutdownHook
{
    public static void main(String[] args) throws InterruptedException
    {
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                System.out.println("Shutdown hook ran!");
            }
        });

        while (true)
        {
            Thread.sleep(1000);
        }
    }
}
在任何程序中都无法真正优雅地处理
kill-9

在极少数情况下,虚拟的 机器可能会中止,即停止 在没有完全关闭的情况下运行。 当虚拟机 例如,在外部终止 在Unix或 终止对Microsoft的进程调用 窗户

处理
kill-9
的唯一实际选择是让另一个监视程序监视您的主程序离开,或者使用包装器脚本。您可以使用shell脚本轮询
ps
命令,在列表中查找您的程序,并在程序消失时执行相应操作

#!/usr/bin/env bash

java TestShutdownHook
wait
# notify your other app that you quit
echo "TestShutdownHook quit"

您可以使用
Runtime.getRuntime().addShutdownHook(…)
,但不能保证在任何情况下都会调用它。

您可以使用
Runtime.getRuntime().addShutdownHook(…)
,但是不能保证在任何情况下都会调用它。

在某些JVM中,有一些方法可以处理您自己的信号——例如,请参阅

通过使用Sun internal
Sun.misc.Signal.handle(Signal,SignalHandler)
方法调用,您还可以注册一个信号处理程序,但可能无法注册JVM使用的
INT
TERM
等信号

为了能够处理任何信号,您必须跳出JVM,进入操作系统领域

我通常对你做什么(