使用java编写大型系统时,往往需要在程序被kill时将内存中的一些临时数据和状态处理掉,这里称之为优雅关闭。介绍两种比较典型的方法:
1. 调用Runtime.getRuntime().addShutdownHook()方法,添加结束时运行的线程。
public void stopGracefully() {
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
}
});
}
2. 实现SignalHandler
public class KillHandler implements SignalHandler {
public void registerSignal(String signalName) {
Signal signal = new Signal(signalName);
Signal.handle(signal, this);
}
@Override
public void handle(Signal signal) {
if (signal.getName().equals("TERM")) {
//
} else if (signal.getName().equals("INT") || signal.getName().equals("HUP")) {
//
} else {
//
}
}
}
程序启动时实例化一个KillHandler,注册TERM信号。
KillHandler killHandler = new KillHandler();
killHandler.registerSignal("TERM");
这样,在进程被kill的时候就会触发KillHandler的handle方法。
两种方法的区别在于,第一种方法在进程被kill的时候main函数就已经结束了,仅会运行shutdownHook中run()方法的代码。
而第二种方法中handle函数会在进程被kill时收到TERM信号,对main函数的运行不会有任何影响,我们需要自己在main函数中添加布尔类型的flag,当收到TERM信号时修改该flag,程序便会正常结束。