通过关闭钩子,我们可以在应用关闭时做一些自定义的操作,让程序更优雅的结束。
JAVA程序运行在虚拟机上(JVM),JAVA程序执行完成,JVM也随之关闭。关闭的方式有多种,根据其行为的文明程度可大概分为两种:
正常关闭 所有普通线程(非守护线程)执行完毕 System.exit(status) Ctrl - C ...
强行关闭 kill进程 Runtime.halt(status) ...
JVM关闭钩子DEMO
public class Main {
public static void main(String[] args) throws Exception {
Runtime.getRuntime().addShutdownHook(new MyHook());
System.out.println("结束吧");
}
public static class MyHook extends Thread {
@Override
public void run() {
System.out.println("你先走,我垫后");
}
}
}
/* 输出:
结束吧
你先走,我垫后
*/
自定义钩子如何注册
public class Runtime {
// 钩子对象必须是一个Thread(或其子类)
public void addShutdownHook(Thread hook) {
// 看起来是个权限检查
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("shutdownHooks"));
}
// 真正的注册逻辑在这个类里面
ApplicationShutdownHooks.add(hook);
}
}
class ApplicationShutdownHooks {
// 钩子集合
private static IdentityHashMap<Thread, Thread> hooks;
// 注册一个钩子
static synchronized void add(Thread hook) {
if(hooks == null)
throw new IllegalStateException("Shutdown in progress");
// 看来注册前不能让Thread跑起来
if (hook.isAlive())
throw new IllegalArgumentException("Hook already running