浅析java的退出钩子(Hook)

简介: 浅析java的退出钩子(Hook)
  • 钩子作用是啥

当你怕退出jvm时中断应用正在处理的任务,从而导致各种问题时。此时钩子就派上了用场。当然你直接拔电源、kill -9再牛逼的机制也不管用了。

  • 怎么用
public static void main(String[] args) {   

        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hook shut down");
            }
        }));
        System.out.println("123");
    }

运行这段代码输出

123
hook shut down
  • 啥原理

首先,将我们新实例化的线程作为参数调用ApplicationShutdownHooks的add方法

public void addShutdownHook(Thread hook) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("shutdownHooks"));
        }
        ApplicationShutdownHooks.add(hook);
    }
    

再来看add方法中经过一些校验之后将其放到map中,那么这个hooks的map怎么来的

private static IdentityHashMap<Thread, Thread> hooks;
static synchronized void add(Thread hook) {
        if(hooks == null)
            throw new IllegalStateException("Shutdown in progress");

        if (hook.isAlive())
            throw new IllegalArgumentException("Hook already running");

        if (hooks.containsKey(hook))
            throw new IllegalArgumentException("Hook previously registered");

        hooks.put(hook, hook);
    }

我们都知道类的初始化早于实例化,那么static代码块首先运行,肯定就回创建map对象,此时在static中又调用了 Shutdown的add方法,我们再继续看

ApplicationShutdownHooks类
static {
        try {
            Shutdown.add(1 /* shutdown hook invocation order */,
                false /* not registered if shutdown in progress */,
                new Runnable() {
                    public void run() {
                        runHooks();
                    }
                }
            );
            hooks = new IdentityHashMap<>();
        } catch (IllegalStateException e) {
            // application shutdown hooks cannot be added if
            // shutdown is in progress.
            hooks = null;
        }
    }

会将ApplicationShutdownHooks类实例化的Runnable添加到Shutdown类的hooks中。

Shutdown类
static void add(int slot, boolean registerShutdownInProgress, Runnable hook) {
        synchronized (lock) {
            if (hooks[slot] != null)
                throw new InternalError("Shutdown hook at slot " + slot + " already registered");

            if (!registerShutdownInProgress) {
                if (state > RUNNING)
                    throw new IllegalStateException("Shutdown in progress");
            } else {
                if (state > HOOKS || (state == HOOKS && slot <= currentRunningHook))
                    throw new IllegalStateException("Shutdown in progress");
            }

            hooks[slot] = hook;
        }
    }

其次,经过以上步骤已经将钩子添加了,那么当jvm退出时是怎么触发的。
当我们运行上述代码时在
java.lang.ApplicationShutdownHooks#runHooks中打断点,然后如下图,
在这里插入图片描述 此时我们的main线程已退出,一个叫DestroyJavaVM的线程被激活,那么这个DestroyJavaVM是怎么被激活的呢。
《Java性能优化权威指南》中有如下一段解释,而上图中的调用栈也清晰的说明了调用顺序。
在这里插入图片描述
最后,经过以上步骤,我们添加的hook被调用,完成了退出jvm时优雅的关闭服务。

相关文章
|
6月前
|
Java 数据库连接 开发者
Java的Shutdown Hook机制:优雅地关闭应用程序
Java的Shutdown Hook机制:优雅地关闭应用程序
253 1
【JavaSE专栏16】Java 的循环退出语句 break、continue
【JavaSE专栏16】Java 的循环退出语句 break、continue
115 0
【JavaSE专栏16】Java 的循环退出语句 break、continue
|
小程序 Java
GE IS220PDIAH1A 336A4940CSP1 Java程序要带着错误代码退出
GE IS220PDIAH1A 336A4940CSP1 Java程序要带着错误代码退出
88 0
GE IS220PDIAH1A 336A4940CSP1 Java程序要带着错误代码退出
|
Java API
Java虚拟机关闭钩子(Shutdown hook)
Shutdown hook是Jvm关闭的钩子,是通过Runtime#addShutdownHook(Thread hook)方法来实现的,根据api是注解可知它就是一系例的已初始化但尚未执行的线程对象。我们可以通过向Jvm注册一个钩子,实现在程序退出时关闭资源、平滑退出的功能。所谓的优雅停机也可以这么搞。
361 0
|
Java 数据库连接 Spring
Java基础内容之JVM钩子hooks函数
请问在Spring中,如果JVM异常终止,Spring是如何保证会释放掉占用的资源,比如说数据库连接等资源呢? 钩子函数非常简单,简单到小编只用摘抄一段Spring代码即可。走你,现在开始。
349 0
|
JavaScript Java 数据安全/隐私保护
Java实现登录功能(含修改密码 退出登录等)
Java实现登录功能(含修改密码 退出登录等)
1909 0
Java实现登录功能(含修改密码 退出登录等)
|
消息中间件 缓存 供应链
【小家java】记录Java守护线程使用时因忽略细节,导致的一个线上问题的排查过程(守护线程异常退出)
【小家java】记录Java守护线程使用时因忽略细节,导致的一个线上问题的排查过程(守护线程异常退出)
【小家java】记录Java守护线程使用时因忽略细节,导致的一个线上问题的排查过程(守护线程异常退出)
|
Java
Java - Main 函数启动不退出的方法
Java - Main 函数启动不退出的方法
812 0
《Java 7程序设计入门经典》一3.13 使用break语句退出循环
本节书摘来自华章出版社《Java 7程序设计入门经典》一书中的第3章,第3.13节,作者 (美)Herbert Schildt Dale Skrien,更多章节内容可以访问云栖社区“华章计算机”公众号查看
1274 0
下一篇
无影云桌面