ShutdownHook原理

Java的ShutdownHook允许在进程结束时执行清理任务。本文介绍了ShutdownHook的注册、执行顺序,以及在`Shutdown.exit`和`Shutdown.shutdown`触发点的详细过程。ShutdownHook分为系统级和应用级,系统级是同步有序执行,应用级则异步执行。当使用`kill -9`信号时,ShutdownHook不会执行。
摘要由CSDN通过智能技术生成

微信搜索“捉虫大师”,点赞、关注是对我最大的鼓励,本文已收录于 https://github.com/lkxiaolou/lkxiaolou

ShutdownHook介绍

在java程序中,很容易在进程结束时添加一个钩子,即ShutdownHook。通常在程序启动时加入以下代码即可

Runtime.getRuntime().addShutdownHook(new Thread(){
   
    @Override
    public void run() {
   
        System.out.println("I'm shutdown hook...");
    }
});

有了ShutdownHook我们可以

  • 在进程结束时做一些善后工作,例如释放占用的资源,保存程序状态等
  • 为优雅(平滑)发布提供手段,在程序关闭前摘除流量

不少java中间件或框架都使用了ShutdownHook的能力,如dubbo、spring等。

spring中在application context被load时会注册一个ShutdownHook。
这个ShutdownHook会在进程退出前执行销毁bean,发出ContextClosedEvent等动作。
而dubbo在spring框架下正是监听了ContextClosedEvent,调用dubboBootstrap.stop()来实现清理现场和dubbo的优雅发布,spring的事件机制默认是同步的,所以能在publish事件时等待所有监听者执行完毕。

ShutdownHook原理

ShutdownHook的数据结构与执行顺序

  • 当我们添加一个ShutdownHook时,会调用ApplicationShutdownHooks.add(hook),往ApplicationShutdownHooks类下的静态变量private static IdentityHashMap<Thread, Thread> hooks添加一个hook,hook本身是一个thread对象
  • ApplicationShutdownHooks类初始化时会把hooks添加到Shutdownhooks中去,而Shutdownhooks是系统级的ShutdownHook,并且系统级的ShutdownHook由一个数组构成,只能添加10个
  • 系统级的ShutdownHook调用了thread类的run方法,所以系统级的ShutdownHook是同步有序执行的
private static void runHooks() {
   
    for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
   
        try {
   
            Runnable hook;
            synchronized (lock) {
   
                // acquire the lock to make sure the hook registered during
                // shutdown is visible here.
                currentRunningHook = i;
                hook = hooks[i]
Java程序中,可以通过添加关闭钩子(Shutdown Hook)来实现在程序退出时关闭资源和平滑退出的功能。关闭钩子是通过调用Runtime类的addShutdownHook(Thread hook)方法来注册的。当程序退出时,关闭钩子可以在多种场景下被调用,包括程序正常退出、使用System.exit()方法、终端使用Ctrl+C触发的中断、系统关闭以及使用Kill pid命令干掉进程等情况。\[2\] 具体到停止线程的问题,关闭钩子本身并不能直接停止线程。关闭钩子主要用于在程序退出时执行一些清理操作,例如关闭资源、保存数据等。如果需要停止线程,可以通过其他方式来实现,例如使用线程的interrupt()方法来中断线程的执行,或者使用标志位来控制线程的运行状态。关闭钩子可以在程序退出时执行这些停止线程的操作,但本身并不直接负责停止线程。\[2\] 需要注意的是,在使用关闭钩子时,应该谨慎处理资源的关闭和线程的停止,以确保程序能够正常退出并释放资源。同时,关闭钩子的执行顺序是不确定的,因此在编写关闭钩子的代码时,应该考虑到可能的并发和竞争条件,以避免出现意外的问题。\[2\]\[3\] #### 引用[.reference_title] - *1* [ShutdownHook - java中优雅地停止服务](https://blog.csdn.net/zhipengfang/article/details/117451139)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [ShutdownHook Java优雅地停止服务](https://blog.csdn.net/fututadeyoushang/article/details/80941632)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值