日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

java小知識-ShutdownHook(優(yōu)雅關(guān)閉)

京東云 ? 來源:京東物流 崔冬冬 ? 作者:京東物流 崔冬冬 ? 2024-12-19 10:36 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

作者:京東物流 崔冬冬

一、先提出一個問題

我們?nèi)绻贘VM退出的時候做一些事情,比如關(guān)閉遠程鏈接,怎么實現(xiàn)呢?

二、ShutdownHook簡介

java里有個方法Runtime.getRuntime#addShutdownHook,是否了解呢?

ShutdownHook是什么意思呢,看單詞解釋“關(guān)閉鉤子”,addShutdownHook就是添加一個關(guān)閉鉤子,這個鉤子是做什么的呢?能否解決上面的問題?

1、RunTime類

先看一下看源碼RunTime#addShutdownHook方法與解釋。

1.1 方法解釋

核心意思,在Java虛擬機在關(guān)閉時會觸發(fā)一些自己添加的事件。

Registers a new virtual-machine shutdown hook.
The Java virtual machine shuts down in response to two kinds of events:
The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. 
When all the hooks have finished it will then halt. Note that daemon threads will continue to run during the shutdown sequence, as will non-daemon threads if shutdown was initiated by invoking the exit method.

1.2 方法源碼

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

方法內(nèi)部調(diào)用了ApplicationShutdownHooks#add, 我們繼續(xù)往下看。

2、ApplicationShutdownHooks類

2.1 添加鉤子


     private static IdentityHashMap 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);
    }

我們添加了一個鉤子,這個鉤子是個線程,這個線程怎么執(zhí)行的呢? 繼續(xù)看一下此類中的runHooks。

2.2 執(zhí)行鉤子


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) {
                }
            }
        }
    }

執(zhí)行runHooks的時候,會啟動所有的hook線程,什么時候調(diào)用runHooks方法的呢?

2.3 執(zhí)行時機

為什么在系統(tǒng)退出的時候會執(zhí)行添加的hook呢?我們看一下正常的退出操作System#exit方法。

1) 類調(diào)用層級

System->Runtime->Shutdown->ApplicationShutdownHooks

2) 方法調(diào)用

系統(tǒng)退出入口:System#exit

步驟 1-->System#exit

步驟 2-->Runtime#exit;

步驟 3--> Shutdown#exit

步驟 4--> Shutdown#runHooks

步驟 5--> ApplicationShutdownHooks#runHooks

步驟 6-->啟動添加的hook線程

3) 補充一下

為什么步驟4會調(diào)用到步驟5呢?

可以看一下ApplicationShutdownHooks的構(gòu)造函數(shù),在創(chuàng)建的時候,封裝了runHooks方法,放到了Shutdown的鉤子集合里。

如此形成閉環(huán),在系統(tǒng)正常退出的時候,最終執(zhí)行我們添加的hook。

三、舉個例子

了解了基本原理,我們看一下怎么使用的

    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread() {
            @Override
            public void run() {
                System.out.println("等等我");
            }
        };
        Runtime.getRuntime().addShutdownHook(thread);
        System.out.println("程序關(guān)閉"); 
   }
    輸出:
    程序關(guān)閉
    等等我

可以看到,在JVM退出的時候調(diào)用,執(zhí)行了此線程,我們開發(fā)中,哪些場景可以使用呢?

四、應(yīng)用場景

關(guān)閉鏈接、線程、資源釋放、記錄執(zhí)行狀態(tài)等。

五、風險點

1、長時間等待

如果添加的hook線程長時間執(zhí)行,我們的退出命令會一直等待,為什么呢?

舉個例子,我們在執(zhí)行的時候sleep一下

  public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000*300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(new Date()+" 等我5分鐘");
            }
        };
        Runtime.getRuntime().addShutdownHook(thread);
        System.out.println(new Date()+" 程序關(guān)閉");
    }
輸出:
Tue Nov 12 17:37:38 CST 2024 程序關(guān)閉
Tue Nov 12 17:42:38 CST 2024 等我5分鐘

2、原因

JVM在退出的時候會調(diào)用runHooks方法,看一下上面的方法java.lang.ApplicationShutdownHooks#runHooks方法。

關(guān)鍵字 hook.join(); 主線程會等待子線程執(zhí)行完成。

如果程序一直執(zhí)行,不能退出怎么辦?

3、解決方案

1 ) 寫代碼時候控制執(zhí)行邏輯、時長

kill -9 命令 強制退出

六、擴展

1、Runtime.getRuntime#addShutdownHook是面向開發(fā)者

ApplicationShutdownHook#add、Shutdown#add我們都不能直接使用。

2、許多中間件框架也利用addShutdownHook來實現(xiàn)資源回收、清理等操作

比如Spring框架中,使用了ShutdownHook注冊,我們常用的@PreDestroy在Bean銷毀前執(zhí)行一些操作,也是借助其回調(diào)的。

七、總結(jié)

1、本文簡單介紹了一下ShutdownHook使用、原理、風險點。

2、我們工作中可以自己注冊ShutdownHook,主動釋放一些資源,降低風險。

3、小知識分享,不足之處歡迎大家指正,關(guān)于java里的知識點也歡迎大家討論分享。

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JAVA
    +關(guān)注

    關(guān)注

    20

    文章

    3012

    瀏覽量

    116880
  • JVM
    JVM
    +關(guān)注

    關(guān)注

    0

    文章

    161

    瀏覽量

    13090
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    SGG-北京總部Java20250625-12月結(jié)課

    教學(xué)基礎(chǔ)上,前瞻性地引入了 AI 相關(guān)的工程化技術(shù)。學(xué)員們學(xué)習了如何在 Java 后端中集成大模型 API,構(gòu)建智能客服或輔助決策系統(tǒng),并了解了 RAG(檢索增強生成)在企業(yè)知識庫搭建中的應(yīng)用。這種
    發(fā)表于 05-01 17:33

    黑馬-Java+AI新版V16零基礎(chǔ)就業(yè)班百度云網(wǎng)盤下載+Java+AI全棧開發(fā)工程師

    傳統(tǒng)開發(fā)升級,Java+AI 融合開發(fā)精講——構(gòu)建下一代企業(yè)級智能應(yīng)用的技術(shù)棧重塑 在人工智能加速滲透至各行各業(yè)的當下,Java 開發(fā)者正面臨一個關(guān)鍵轉(zhuǎn)折點:要么被動旁觀 AI 能力的邊緣化集成
    發(fā)表于 05-01 11:29

    [完結(jié)15章]Java轉(zhuǎn) AI高薪領(lǐng)域必備-從0到1打通生產(chǎn)級AI Agent開發(fā)

    拒絕原地踏步:Java工程師AI轉(zhuǎn)型的底層技術(shù)破局之道 在軟件工程范式被大語言模型(LLM)徹底顛覆的今天,傳統(tǒng)的“Java CRUD boy”正面臨著前所未有的生存危機。當業(yè)務(wù)邏輯的生成可以被
    發(fā)表于 04-30 13:46

    Java轉(zhuǎn) AI高薪領(lǐng)域必備 從0到1打通生產(chǎn)級AI Agent開發(fā) 教程資料

    告別CRUD內(nèi)卷的經(jīng)濟學(xué):Java程序員轉(zhuǎn)型AI Agent的商業(yè)重構(gòu) 在當前的IT職場生態(tài)中,一個令人不寒而栗的現(xiàn)象正在上演:傳統(tǒng)Java CRUD(增刪改查)開發(fā)者的薪資溢價正在被系統(tǒng)性抹平
    發(fā)表于 04-29 17:08

    TL-JAVA+AI大模型智能應(yīng)用開發(fā)+Java+AI全棧開發(fā)工程師

    獲課:pan.baidu.com/s/16MoRr6EApmBczMhHgKxYaw?pwd=w4wg 數(shù)字化未來升級:Java+AI 全棧驅(qū)動行業(yè)智能轉(zhuǎn)型 在科技迅速發(fā)展的今天,數(shù)字化轉(zhuǎn)型已成為
    的頭像 發(fā)表于 04-28 16:43 ?89次閱讀

    Java并發(fā)編程的“基石”——多線程概念初識

    AI 算力調(diào)度底層:Java 并發(fā)基石與未來技術(shù)融合 當我們在屏幕前流暢地與大語言模型對話,或是看著自動駕駛系統(tǒng)瞬間處理海量視覺數(shù)據(jù)時,往往只會驚嘆于 AI 算法的精妙。然而,在這層絢麗的應(yīng)用外衣
    發(fā)表于 04-16 18:50

    如何關(guān)閉或開啟主設(shè)備Wi-Fi

    有用戶反饋想要關(guān)閉或開啟主FTTR設(shè)備的Wi-Fi,您可以登錄主FTTR的web界面進行操作,具體操作如下:
    的頭像 發(fā)表于 03-12 09:59 ?395次閱讀
    如何<b class='flag-5'>關(guān)閉</b>或開啟主設(shè)備Wi-Fi

    電能質(zhì)量在線監(jiān)測裝置的報警功能可以關(guān)閉嗎?

    電能質(zhì)量在線監(jiān)測裝置的報警功能 能否關(guān)閉及如何關(guān)閉,取決于裝置的設(shè)計、功能等級和具體配置 。以下是詳細分析: 一、核心結(jié)論:報警功能可部分關(guān)閉,但安全相關(guān)報警通常不可禁用 多數(shù)裝置支持選擇性關(guān)
    的頭像 發(fā)表于 11-05 13:38 ?610次閱讀

    Arm Neoverse CPU上大代碼量Java應(yīng)用的性能測試

    Java 是互聯(lián)網(wǎng)領(lǐng)域廣泛使用的編程語言。Java 應(yīng)用的一些特性使其性能表現(xiàn)與提前編譯的原生應(yīng)用(例如 C 程序)大相徑庭。由于 Java 字節(jié)碼無法直接在 CPU 上執(zhí)行,因此通常運行時在
    的頭像 發(fā)表于 11-05 11:25 ?966次閱讀
    Arm Neoverse CPU上大代碼量<b class='flag-5'>Java</b>應(yīng)用的性能測試

    交易關(guān)閉自動處理接口

    ? ?在電商、支付系統(tǒng)或任何交易密集型應(yīng)用中,交易關(guān)閉(如用戶取消訂單、支付超時或系統(tǒng)異常)是常見事件。手動處理這些事件效率低下且易出錯,因此開發(fā)一個自動處理接口至關(guān)重要。本文將從需求分析、工作原理
    的頭像 發(fā)表于 10-17 14:25 ?638次閱讀
    交易<b class='flag-5'>關(guān)閉</b>自動處理接口

    Java效率提升指南:5個Java工具選型建議及Perforce JRebel和XRebel介紹

    企業(yè)級Java環(huán)境越來越復(fù)雜,真正的破局點,可能不在“人”,而在于“工具”。5個實用建議,幫你理清Java工具的選型思路。
    的頭像 發(fā)表于 09-11 13:59 ?1993次閱讀
    <b class='flag-5'>Java</b>效率提升指南:5個<b class='flag-5'>Java</b>工具選型建議及Perforce JRebel和XRebel介紹

    Perforce JRebel 簡介:即時加載代碼變更,加速Java應(yīng)用開發(fā)

    Perforce JRebel 專為Java開發(fā)提速而生!支持跳過構(gòu)建與重新部署,實時加載代碼變更,支持100+框架,無縫集成主流IDE與應(yīng)用服務(wù)器。
    的頭像 發(fā)表于 08-14 14:35 ?1001次閱讀
    Perforce JRebel 簡介:即時加載代碼變更,加速<b class='flag-5'>Java</b>應(yīng)用開發(fā)

    A21:分立元件知識與應(yīng)用專題--電感知識及應(yīng)用案例

    分立元件知識與應(yīng)用專題--電感知識及應(yīng)用案例
    的頭像 發(fā)表于 07-15 19:24 ?541次閱讀
    A21:分立元件<b class='flag-5'>知識</b>與應(yīng)用專題--電感<b class='flag-5'>知識</b>及應(yīng)用案例

    A21:分立元件知識與應(yīng)用專題--電容知識及應(yīng)用案例

    分立元件知識與應(yīng)用專題--電容知識及應(yīng)用案例
    的頭像 發(fā)表于 07-15 19:22 ?544次閱讀
    A21:分立元件<b class='flag-5'>知識</b>與應(yīng)用專題--電容<b class='flag-5'>知識</b>及應(yīng)用案例

    EtherCAT運動控制卡應(yīng)用開發(fā)教程之Java

    運動控制卡的Java開發(fā)及DLL調(diào)用
    的頭像 發(fā)表于 06-13 14:29 ?1037次閱讀
    EtherCAT運動控制卡應(yīng)用開發(fā)教程之<b class='flag-5'>Java</b>
    镇安县| 阿克苏市| 连云港市| 井陉县| 嘉义市| 东莞市| 大姚县| 钦州市| 怀远县| 伊吾县| 郸城县| 富顺县| 凭祥市| 买车| 平邑县| 仁怀市| 东山县| 略阳县| 五常市| 汝南县| 会泽县| 黄大仙区| 宁国市| 印江| 昌图县| 兴海县| 商都县| 满洲里市| 木兰县| 唐山市| 手游| 曲阳县| 庆城县| 江津市| 郎溪县| 湘西| 潮州市| 阳曲县| 岳西县| 重庆市| 怀远县|