国产精品久久久aaaa,日日干夜夜操天天插,亚洲乱熟女香蕉一区二区三区少妇,99精品国产高清一区二区三区,国产成人精品一区二区色戒,久久久国产精品成人免费,亚洲精品毛片久久久久,99久久婷婷国产综合精品电影,国产一区二区三区任你鲁

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

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

3天內不再提示

java小知識-ShutdownHook(優雅關閉)

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

掃碼添加小助手

加入工程師交流群

作者:京東物流 崔冬冬

一、先提出一個問題

我們如果在JVM退出的時候做一些事情,比如關閉遠程鏈接,怎么實現呢?

二、ShutdownHook簡介

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

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

1、RunTime類

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

1.1 方法解釋

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

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

方法內部調用了ApplicationShutdownHooks#add, 我們繼續往下看。

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

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

2.2 執行鉤子


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

執行runHooks的時候,會啟動所有的hook線程,什么時候調用runHooks方法的呢?

2.3 執行時機

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

1) 類調用層級

System->Runtime->Shutdown->ApplicationShutdownHooks

2) 方法調用

系統退出入口:System#exit

步驟 1-->System#exit

步驟 2-->Runtime#exit;

步驟 3--> Shutdown#exit

步驟 4--> Shutdown#runHooks

步驟 5--> ApplicationShutdownHooks#runHooks

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

3) 補充一下

為什么步驟4會調用到步驟5呢?

可以看一下ApplicationShutdownHooks的構造函數,在創建的時候,封裝了runHooks方法,放到了Shutdown的鉤子集合里。

如此形成閉環,在系統正常退出的時候,最終執行我們添加的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("程序關閉"); 
   }
    輸出:
    程序關閉
    等等我

可以看到,在JVM退出的時候調用,執行了此線程,我們開發中,哪些場景可以使用呢?

四、應用場景

關閉鏈接、線程、資源釋放、記錄執行狀態等。

五、風險點

1、長時間等待

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

舉個例子,我們在執行的時候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()+" 程序關閉");
    }
輸出:
Tue Nov 12 17:37:38 CST 2024 程序關閉
Tue Nov 12 17:42:38 CST 2024 等我5分鐘

2、原因

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

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

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

3、解決方案

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

kill -9 命令 強制退出

六、擴展

1、Runtime.getRuntime#addShutdownHook是面向開發者

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

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

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

七、總結

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

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

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

審核編輯 黃宇

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

    關注

    20

    文章

    3001

    瀏覽量

    116430
  • JVM
    JVM
    +關注

    關注

    0

    文章

    161

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    開發知識庫測試添加知識

    文檔類型的知識要等待數據校驗完成后才能上架 可以點擊知識名稱查看知識詳情 等待后端處理完成可以點擊知識列表的上架 在智能體中知識庫的位置點
    發表于 03-06 15:07

    freertos關閉任務調度的方法

    #include \"FreeRTOS.h\" #include \"task.h\" /* 關閉任務調度 */ void
    發表于 11-17 06:47

    電能質量在線監測裝置的報警功能可以關閉嗎?

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

    Arm Neoverse CPU上大代碼量Java應用的性能測試

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

    Java 25正式發布,重要特性詳解(附代碼示例):靈活構造函數體、模塊導入聲明、AOT方法分析等

    Java 25現已發布,更多新特性來了!配合Perforce JRebel,代碼修改即時生效,無需重啟服務,即可實現“改完就看效果”。新特性+快工具,讓你的Java開發體驗雙倍提升!
    的頭像 發表于 10-29 13:16 ?1419次閱讀
    <b class='flag-5'>Java</b> 25正式發布,重要特性詳解(附代碼示例):靈活構造函數體、模塊導入聲明、AOT方法分析等

    交易關閉自動處理接口

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

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

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

    Java 在物聯網與嵌入式系統中的應用前景與挑戰

    引言 隨著物聯網與嵌入式技術的快速發展,設備端的軟件開發需求不斷增加。傳統上,嵌入式設備多使用 C、C++ 進行開發,但近年來,Java 逐漸成為物聯網領域的重要角色。憑借其跨平臺特性、豐富
    的頭像 發表于 09-04 14:49 ?988次閱讀

    Perforce JRebel 簡介:即時加載代碼變更,加速Java應用開發

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

    A21:分立元件知識與應用專題--電感知識及應用案例

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

    A21:分立元件知識與應用專題--電容知識及應用案例

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

    EtherCAT運動控制卡應用開發教程之Java

    運動控制卡的Java開發及DLL調用
    的頭像 發表于 06-13 14:29 ?888次閱讀
    EtherCAT運動控制卡應用開發教程之<b class='flag-5'>Java</b>

    Java開發者必備的效率工具——Perforce JRebel是什么?為什么很多Java開發者在用?

    Perforce JRebel是一款Java開發效率工具,旨在幫助java開發人員更快地編寫更好的應用程序。JRebel可即時重新加載對代碼的修改,無需重啟或重新部署應用程序,就能讓開發者即時看到代碼更改的效果,從而縮短開發、調試和測試周期,大大提升開發效率。
    的頭像 發表于 04-27 13:44 ?852次閱讀
    <b class='flag-5'>Java</b>開發者必備的效率工具——Perforce JRebel是什么?為什么很多<b class='flag-5'>Java</b>開發者在用?

    推薦!如何優雅地擺好PCB絲印?

    很多畫PCB的人,會認為絲印不影響電路的性能,所以,對絲印并不重視。但是,對于一個專業的硬件工程師來說,必須重視這些細節。 下面介紹如何優雅地弄好PCB絲印。 1 擺放的位置 一般來說,電阻、電容
    發表于 04-08 14:59

    我只會Java,憑什么不能玩轉樹莓派?GPIO操控竟比C++更優雅~

    導語當全球開發者默認將Python視為樹莓派的"母語"時,一個顛覆認知的工具鏈正在Java開發者群體中口口相傳——Pi4J讓Java代碼直接操控GPIO、I2C、SPI等硬件接口
    的頭像 發表于 03-25 09:21 ?1128次閱讀
    我只會<b class='flag-5'>Java</b>,憑什么不能玩轉樹莓派?GPIO操控竟比C++更<b class='flag-5'>優雅</b>~