Java 收到信号后,优雅地关闭应用程序

Java 收到信号后,优雅地关闭应用程序,java,signals,shutdown,Java,Signals,Shutdown,我正在考虑如何编写一个信号处理程序,通知主线程需要退出 我想的是: 1使用以下代码截取信号 SignalHandler handler = new SignalHandler () { public void handle(Signal sig) { System.out.println("Signal " + sig); System.out.println("Shutting down..."); ServiceLocator.P

我正在考虑如何编写一个信号处理程序,通知主线程需要退出

我想的是:

1使用以下代码截取信号

SignalHandler handler = new SignalHandler () {
      public void handle(Signal sig) {
        System.out.println("Signal " + sig);
        System.out.println("Shutting down...");

        ServiceLocator.ProgramState().setMustExit();

        System.exit(0);
      }
    };
Signal.handle(new Signal("INT"), handler);
Signal.handle(new Signal("TERM"), handler);
2设置一个ProgramState对象以指示需要退出:ServiceLocator.ProgramState.setMustExit

3将以下代码放入程序的某些部分,以检查ProgramState是否告诉我退出:

if (ServiceLocator.ProgramState().mustExit()) {
    throw new MustExitException();
}
异常将被干净退出的主线程接收

我不太喜欢像我将要做的那样抛出一个异常,但这似乎是实现我目标的一个快速方法


还有其他方法可以正常退出吗?

主线程通常直接或间接地等待某个事件/通知,以防止它立即终止程序

一个干净的关机就是让主线程知道是时候继续运行了,或者中断它,或者通知它。作为结束超出该点的程序执行的路径的一部分,它应该负责终止程序的其他关键部分。在大多数情况下,没有任何关键部分

如果应用程序是单线程的。。。也许不应该。核心执行逻辑应该与主线程分离

SpringIOC/Guice Netflix治理器的存在是为了更好地控制对象图的生命周期

两者都可以帮助您构建一个实现,其中引导/关闭/组件连接与应用程序的实际逻辑分离,并提供管理各种对象/类的生命周期的方便方法

我衷心建议您使用它们,而不是使用自己的关闭机制。当然,保持信号处理功能,但这也应该与主线程分离。你最终会得到一个类似药丸的机制

例如,如果选择使用Spring,则将信号处理程序定义为bean,使用ConfigurableApplicationContext实例将其注入/自动连接,并在收到所需信号时调用其close方法。这将导致所有SpringWired bean执行其定义的关闭/销毁行为

另外,信号处理将起作用,但有更多具体的方法来传递关机消息,请参见ZeroMq/JeroMQ,以获取来自外部源的无代理消息示例