我正在考虑如何编写一个信号处理程序,以通知主线程有关退出的需要。
我在想什么:
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();
}
该异常将被干净退出的主线程感知。
我不喜欢像我将要抛出的异常,但这似乎是实现目标的一种快捷方法。
还有其他方法可以正常退出吗?
答案 0 :(得分:1)
主线程通常等待一些事件/通知(直接或间接),以防止其立即终止程序
彻底关闭将通过中断或通知主线程,让主线程知道是时候进行“启动”了。作为结束程序执行到此为止的一部分,应该注意“终止”程序的其他关键部分(在大多数情况下,没有任何部分)。
如果应用程序是单线程的,那么可能不应该这样。核心执行逻辑应与主线程分开。
Spring IOC / Guice(Netflix管理员)的存在尤其是为了更好地控制对象图的生命周期。
两者都可以帮助您构建一个实现,其中引导程序/关机/组件布线与应用程序的实际逻辑脱钩,并提供了方便的方法来管理各种对象/类的生命周期。
我全心全意地建议您使用它们,而不要使用自己的关闭机制。 (当然,保留信号处理功能,但也应将其与主线程分离)。您最终将获得类似毒药的机制。
例如-如果您选择使用Spring,则将信号处理程序定义为bean,使用ConfigurableApplicationContext
实例注入/自动装配它,并在接收到信号后调用其close()
方法所需信号。这将导致所有弹簧接线豆执行其已定义(如果已定义)的关闭/破坏行为
P.S。信号处理将起作用,但是还有更具体的方法可以从外部来源传达关闭消息(请参阅ZeroMq / JeroMQ,以获取无代理消息示例)。