收到信号后,正常关闭应用程序

时间:2018-10-23 20:48:59

标签: java signals shutdown

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

我在想什么:

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();
}

该异常将被干净退出的主线程感知。

我不喜欢像我将要抛出的异常,但这似乎是实现目标的一种快捷方法。

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

1 个答案:

答案 0 :(得分:1)

主线程通常等待一些事件/通知(直接或间接),以防止其立即终止程序

彻底关闭将通过中断或通知主线程,让主线程知道是时候进行“启动”了。作为结束程序执行到此为止的一部分,应该注意“终止”程序的其他关键部分(在大多数情况下,没有任何部分)。

如果应用程序是单线程的,那么可能不应该这样。核心执行逻辑应与主线程分开。

Spring IOC / Guice(Netflix管理员)的存在尤其是为了更好地控制对象图的生命周期。

两者都可以帮助您构建一个实现,其中引导程序/关机/组件布线与应用程序的实际逻辑脱钩,并提供了方便的方法来管理各种对象/类的生命周期。

我全心全意地建议您使用它们,而不要使用自己的关闭机制。 (当然,保留信号处理功能,但也应将其与主线程分离)。您最终将获得类似毒药的机制。

例如-如果您选择使用Spring,则将信号处理程序定义为bean,使用ConfigurableApplicationContext实例注入/自动装配它,并在接收到信号后调用其close()方法所需信号。这将导致所有弹簧接线豆执行其已定义(如果已定义)的关闭/破坏行为

P.S。信号处理将起作用,但是还有更具体的方法可以从外部来源传达关闭消息(请参阅ZeroMq / JeroMQ,以获取无代理消息示例)。