1 JDK关闭钩子
在很多应用场景下,程序退出后,需要做一些善后处理,JDK提供了 关闭钩子 。除了kill -9 程序之外,对于System.exit()、CTRL+C中止程序之后,都会触发已注册的关闭钩子。钩子有点类似于try…catch中finally操作。
关闭钩子 本是一个线程。举例如下:
1、定义一个关闭钩子
1 2 3 4 5 6 7 |
public class AppHook extends Thread{ @Override public void run() { System.out.printf("hook shut down"); } } |
2、注册关闭钩子
1 2 3 4 5 6 7 8 9 |
public class HookTest { public static void main(String[] args) { // 注册钩子 Runtime.getRuntime().addShutdownHook(new AppHook()); // 程序结束 System.out.println("app finish"); } } |
执行
1 2 |
app finish hook shut down |
2 Tomcat关闭钩子
Tomcat中也有使用关闭钩子,在Catalinal的start方法有如下代码:
1 2 3 4 5 6 7 8 |
if (useShutdownHook) { if (shutdownHook == null) { shutdownHook = new CatalinaShutdownHook(); } // 加载钩子 Runtime.getRuntime().addShutdownHook(shutdownHook); .. } |
钩子定义如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
protected class CatalinaShutdownHook extends Thread { @Override public void run() { try { if (getServer() != null) { Catalina.this.stop(); } } catch (Throwable ex) { ExceptionUtils.handleThrowable(ex); log.error(sm.getString("catalina.shutdownHookFail"), ex); } finally { // If JULI is used, shut JULI down *after* the server shuts down // so log messages aren't lost LogManager logManager = LogManager.getLogManager(); if (logManager instanceof ClassLoaderLogManager) { ((ClassLoaderLogManager) logManager).shutdown(); } } } } |