利用JVM钩子函数优雅关闭线程池

核心API:

  • shutDown
  • shutDownNow
  • awaitTermination

利用JVM钩子函数,在虚拟机关闭时调用相关方法即”优雅关闭线程池”。

先通过shutdown等待线程池自身结束,然后等待一段时间,如果没有成功,再调用shutdownNow将等待I/O的任务中断并退出。


    /**
     * 添加钩子函数
     */
    private void initGracefullyShutDown() {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> shutDownThreadPool(asyncExecutor, "BASE")));
        aliasExecutors.forEach((alias, threadPoolExecutor) ->
                Runtime.getRuntime().addShutdownHook(new Thread(() -> shutDownThreadPool(threadPoolExecutor, alias)))
        );
    }

    /**
    * 优雅关闭线程池。
    *  自身关闭,await 60s,强制关闭。
    */
    private void shutDownThreadPool(ExecutorService threadPool, String alias) {
        log.info("Start to shutdown the thead pool : {}", alias);

        threadPool.shutdown();
        try {
            if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
                threadPool.shutdownNow();
                log.warn("Interrupt the worker, which may cause some task inconsistent");

                if (!threadPool.awaitTermination(60, TimeUnit.SECONDS)) {
                    log.warn("Thread pool can't be shutdown even with interrupting worker threads, which may cause some task inconsistent.");
                }
            }
        } catch (InterruptedException ie) {
            threadPool.shutdownNow();
            log.warn("The current server thread is interrupted when it is trying to stop the worker threads. This may leave an inconsistent state.");

            Thread.currentThread().interrupt();
        }
    }

备注:本来是循环调用shutDownThreadPool()方法, 后来发现阻塞严重,追了下源码修改成了循环添加钩子了,具体看如下。

JVM钩子函数

自身没有细追源码,简单看了几篇其他伙伴记录的博客。

  • 虚拟机退出 :JVM会在所有非守护(后台)线程关闭后才会退出 (关于守护线程,随便看了几篇博客回忆下,这篇还不错。《大白话讲解守护线程》)
  • 系统调用System.exit(0)
  • JVM正常退出(Linux上kill命令也会调用钩子函数)

追了一下源码,看了下,发现是一个集合维护Threads。(即咱们调用API,add进去的)

ApplicationShutdownHooks.java

    /* Iterates over all application hooks creating a new thread for each
     * to run in. Hooks are run concurrently and this method waits for
     * them to finish.

     */
    static void runHooks() {
        Collection threads;
        synchronized(ApplicationShutdownHooks.class) {
            threads = hooks.keySet();
            hooks = null;
        }

        for (Thread hook : threads) {
            hook.start();
        }
        for (Thread hook : threads) {
            while (true) {
                try {
                    hook.join();
                    break;
                } catch (InterruptedException ignored) {
                }
            }
        }
    }
}

Original: https://www.cnblogs.com/deepSleeping/p/14976815.html
Author: DeepSleeping丶
Title: 利用JVM钩子函数优雅关闭线程池

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/714794/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【JAVA】排序算法之选择排序

    1.前言 基础排序算法,旨在简单易懂讲解算法逻辑和思路,以下均使用 升序方式来讲解和实现算法。 2.思路 选择排序重在 选择二字,比如给定一串数字 5 3 4 1 2,我们选定第一…

    技术杂谈 2023年6月21日
    070
  • pdf文件 a4转到手机

    pdf文件 a4转到手机 pdf文件 a4转到手机 pdf文件 a4转到手机 人工智能演示 ……. 计算….. Original: https:…

    技术杂谈 2023年5月31日
    075
  • C++ STL 常用容器概述

    前排提醒: 由于 Microsoft Docs 全是机翻。所以本文表格是我人脑补翻+审校。 如果有纰漏、模糊及时反馈。 了解每一种容器的特性、知道什么情况下用什么容器就可以。 序列…

    技术杂谈 2023年6月21日
    084
  • centos 7 安装zabbix 4.0

    一、zabbix简介 1、简介 zabbix([`zæbiks])是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix能监视各种网络参数如:…

    技术杂谈 2023年7月10日
    061
  • codepage IMLangCodePages

    http://baike.baidu.com/link?url=78DSTGAri8dvHNLQ03rThSKieJqhFwFWL4sQMao6cfaRSOUWN88QVBwmSJ…

    技术杂谈 2023年5月31日
    083
  • Spark学习(4)SparkStreaming

    Apache Flink SparkSteaming Storm 架构介于spark和storm之间,主从结构与sparkStreaming相似,DataFlow Grpah与st…

    技术杂谈 2023年7月24日
    068
  • Game Engine Architecture 9

    【 Game Engine Architecture 9】 1、Formatted Output with OutputDebugString() int VDebugPrintF…

    技术杂谈 2023年5月31日
    076
  • docker 报错:不能选择设备驱动 could not select device driver 的解决方法(实测有效)

    Ubuntu安装完docker引擎后,在创建容器的时候指定 –gpus all,出现报错如下: 报错: docker: Error response from daem…

    技术杂谈 2023年7月10日
    087
  • max30100心率血氧健康传感器调试总结备忘

    前记 在健康监测领域,心率血氧传感器是一个非常重要的前端采集设备。了解,研究并使用它,是一个方案商的基本素质。鉴于此,笔者花了一些时间在不同的硬件平台来使用它。中间遇到了一些问题值…

    技术杂谈 2023年5月31日
    071
  • SQL语句复习整理

    SQL语句SQL 是用于访问和处理数据库的标准的计算机语言,SQL 指结构化查询语言 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL)。 SQL…

    技术杂谈 2023年6月21日
    098
  • Spring实战入门,带你轻松掌握Spring框架

    Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架,它是为了解决企业应用开发的复杂性而创建的。Spring 的核心是控制反转(IoC)和面向切面编程(AOP)。…

    技术杂谈 2023年7月25日
    072
  • python爬取百度图片

    首先通过 urllib获取网页的源码 获取下一页的url链接,当本页的图片链接获取完毕,再继续获取下一页的。使用Python正则表达式匹配需要的字段 获取每一页的图片链接,将之放入…

    技术杂谈 2023年7月25日
    054
  • NTP和chrony时间同步

    古代计时方式 ●在远古时期,人类用来确定时间的方式是一些自然界”相对”亘古不变的周期。如地球的公转是为一年,月球的公转是为一月,地球的自转是为一天等,最早的…

    技术杂谈 2023年7月24日
    081
  • SSH加密原理

    1、SSH初次交换公钥 客户端发起链接请求 服务端返回自己的公钥,以及一个会话ID(这一步客户端得到服务端公钥) 客户端生成密钥对 客户端用自己的公钥异或会话ID,计算出一个值Re…

    技术杂谈 2023年7月24日
    086
  • NFS 与 NAS 是什么关系

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    技术杂谈 2023年5月31日
    087
  • 使用IntelliJ IDEA 配置Maven(入门)

    1. 下载Maven 官方地址:http://maven.apache.org/download.cgi 解压并新建一个本地仓库文件夹 2.配置本地仓库路径 3.配置maven环境…

    技术杂谈 2023年5月31日
    086
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球