利用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)

大家都在看

  • Bash编程中对字符串的操作

    Bash的字符串操作 String="Hello World" #获取字符串长度,获取字符长度的变量调用应该使用${},这里大括号是必须的 #例1-1 echo…

    技术杂谈 2023年6月21日
    092
  • 初学者入门:使用WordPress搭建一个专属自己的博客

    体验简介 阿里云云起实验室提供相关实验资源,点击前往 场景将提供一台基础环境为CentOS 的ECS(云服务器)实例,这台服务器上已经内置LAMP环境。我们将会在这台服务器上安装 …

    技术杂谈 2023年7月11日
    090
  • JAVA的线程

    JAVA的线程 1.1线程与进程 进程:是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。简单来说,一个进程就…

    技术杂谈 2023年6月21日
    096
  • 登录页面和FORM的职责不对称,处理方法,刷新工作流程

    登录页面和FORM的职责不对称,处理方法,刷新工作流程: Original: https://www.cnblogs.com/quanweiru/p/9219829.htmlAut…

    技术杂谈 2023年6月1日
    082
  • ElasticSearch(二)检索的进阶

    ElasticSearch(二)检索的进阶 检索的进阶 SearchAPI ES支持两种基本方式的检索: https://www.elastic.co/guide/en/elast…

    技术杂谈 2023年7月10日
    092
  • 你真的了解word-wrap和word-break的区别吗?

    这两个东西是什么,我相信至今还有很多人搞不清,只会死记硬背的写一个word-wrap:break-word;word-break:break-all;这样的东西来强制断句,又或者是…

    技术杂谈 2023年5月31日
    092
  • X-Y问题

    什么是X-Y问题 X-Y问题就是有人想解决问题X,他觉得Y可能是解决X的方法但不知道Y怎么做;在我们的工作中,需求方给出的来的是Y,而软件工程师不知道需要解决的X是什么。 我理解的…

    技术杂谈 2023年7月25日
    064
  • mybatis总结

    第一步 第二步 <build>        <resources>       &#…

    技术杂谈 2023年7月11日
    087
  • 浅谈K库(转)

    首先要解释什么是K库,记得当年查遍K开头的单词也没有找到答案,后来才知道所谓的K指的是谐音”characterization”,意思是表征。所谓的K库指的是…

    技术杂谈 2023年6月1日
    095
  • 5. `sklearn`下的线性回归

    以线性回归为例,介绍sklearn包进行机器学习的流程 本文以线性回归为例,介绍使用 sklearn进行机器学习的一般过程。 首先生成模拟数据 import numpy as np…

    技术杂谈 2023年7月10日
    071
  • 利他利己?自利利他?

    利他、利己从来就是一个大问题,但大多数人不是纠结单选题,而是排序题,到底先利己还是先利他? 学佛讲究的是自利利他,因为你连自己都度不了,何谈度众生?我们需要榜样需要以身作则。 可团…

    技术杂谈 2023年5月31日
    099
  • 技术管理进阶——空降Leader如何开展工作?

    原创不易,求分享、求一键三连 前几天有个粉丝咨询了一个的问题: 最近遇到一个 空降Leader,挺苦恼的:新Leader技术很厉害,但平时根本就不管我们,也不愿意了解业务,更像是一…

    技术杂谈 2023年6月1日
    080
  • 使用IntelliJ IDEA查看类的继承关系图形

    1、查看图形形式的继承链 在你想查看的类的标签页内,点击右键,选择 Diagrams,其中有 show 和 show … Popup,只是前者新建在标签页内,后者以浮窗…

    技术杂谈 2023年5月31日
    0108
  • MySQL数据库-数据表(二)

    分析:给 reader 表添加数据. INSERT INTO:插入数据,插入数据的时候会检查主键或者唯一索引,如果出现重复就会报错; 语法:INSERT INTO table_na…

    技术杂谈 2023年6月21日
    097
  • 面向对象和函数式

    阅读前,请先封印以下能力:类、闭包、继承&多态、高阶函数…… 现在,你只会全局变量和函数,开始写一个带 cache 的 fibonacci。 con…

    技术杂谈 2023年7月11日
    0121
  • 个人介绍

    开罐即食。 开罐即食。 posted @2022-09-26 21:57 qAlex_Weiq 阅读(2512 ) 评论() 编辑 Original: https://www.cn…

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