成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java并發(fā)編程:優(yōu)雅的關閉鉤子(Shutdown Hook)

開發(fā) 前端
當程序即將退出時(例如釋放資源、關閉數(shù)據(jù)庫連接等),可以通過預先注冊一個或多個關閉鉤子線程(Shutdown Hook)來執(zhí)行相關操作。當 JVM 進程準備退出時,這些鉤子線程會被觸發(fā)并運行。

關閉鉤子簡介

當程序即將退出時(例如釋放資源、關閉數(shù)據(jù)庫連接等),可以通過預先注冊一個或多個關閉鉤子線程(Shutdown Hook)來執(zhí)行相關操作。當 JVM 進程準備退出時,這些鉤子線程會被觸發(fā)并運行。

示例代碼:

public class HookThreadDemo {
    privatestaticclass HookRunnable implements Runnable {
        @Override
        public void run() {
            try {
                System.out.println("鉤子線程 " + Thread.currentThread().getName() + " 正在執(zhí)行...");
                Thread.sleep(2000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("鉤子線程 " + Thread.currentThread().getName() + " 執(zhí)行結束");
        }
    }

    public static void main(String[] args) {
        HookRunnable hookRunnable = new HookRunnable();
        // 添加鉤子線程 0
        Runtime.getRuntime().addShutdownHook(new Thread(hookRunnable));
        // 添加鉤子線程 1
        Runtime.getRuntime().addShutdownHook(new Thread(hookRunnable));
        System.out.println("主線程即將結束執(zhí)行");
    }
}

輸出結果:

主線程即將結束執(zhí)行
鉤子線程 Thread-0 正在執(zhí)行...
鉤子線程 Thread-1 正在執(zhí)行...
鉤子線程 Thread-1 執(zhí)行結束
鉤子線程 Thread-0 執(zhí)行結束

當主線程執(zhí)行完畢后,JVM 進程退出前,所有注冊的鉤子線程會被啟動并執(zhí)行。

關閉鉤子應用場景

  1. 釋放資源:關閉文件句柄、數(shù)據(jù)庫連接等,避免資源泄漏。
  2. 停止服務:安全關閉服務器,確保所有請求處理完畢。
  3. 發(fā)送通知:通過郵件或短信通知用戶服務已停止。
  4. 記錄日志:保存系統(tǒng)狀態(tài)或錯誤信息,便于后續(xù)排查問題。

數(shù)據(jù)庫連接實戰(zhàn)演示

以下代碼演示如何用關閉鉤子關閉數(shù)據(jù)庫連接:

public class DatabaseConnection {
    privatestatic Connection conn;

    public static void main(String[] args) {
        System.out.println("主線程開始執(zhí)行");
        initConnection(); // 初始化數(shù)據(jù)庫連接
        System.out.println("執(zhí)行數(shù)據(jù)查詢與處理");

        // 注冊關閉鉤子
        Runtime.getRuntime().addShutdownHook(new Thread(() -> closeConnection()));
        System.out.println("主線程結束執(zhí)行");
    }

    private static void initConnection() {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/school_info?useSSL=true&",
                "root", "root"
            );
            System.out.println("數(shù)據(jù)庫連接成功!");
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
    }

    private static void closeConnection() {
        try {
            conn.close();
            System.out.println("數(shù)據(jù)庫連接已關閉!");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

輸出結果:

主線程開始執(zhí)行
數(shù)據(jù)庫連接成功!
執(zhí)行數(shù)據(jù)查詢與處理
主線程結束執(zhí)行
數(shù)據(jù)庫連接已關閉!

使用關閉鉤子的注意事項

  1. 強制終止進程(如kill -9)不會觸發(fā)鉤子線程。
  2. 避免耗時操作:鉤子線程中不要執(zhí)行長時間任務,否則會延遲 JVM 退出。
  3. 禁止異常拋出:鉤子線程中的異??赡軐е?JVM 無法正常退出。
  4. 注冊順序:按依賴關系注冊鉤子,先注冊簡單任務,后注冊復雜任務。
  5. 避免啟動新線程:在鉤子中啟動新線程可能導致 JVM 無法正常關閉。

開源框架中的關閉鉤子機制

1. Spring

在AbstractApplicationContext中,registerShutdownHook()方法注冊鉤子,用于關閉上下文:

public void registerShutdownHook() {
    if (this.shutdownHook == null) {
        this.shutdownHook = new Thread(() -> doClose());
        Runtime.getRuntime().addShutdownHook(this.shutdownHook);
    }
}

2. Tomcat

Tomcat 通過注冊鉤子確保服務關閉時釋放資源:

public void registerShutdownHook() {
    if (this.shutdownHook == null) {
        this.shutdownHook = new Thread(() -> {
            synchronized (startupShutdownMonitor) {
                doClose();
            }
        });
        Runtime.getRuntime().addShutdownHook(this.shutdownHook);
    }
}

關閉鉤子機制的原理

JVM 啟動時,主線程會創(chuàng)建一個關閉線程(Shutdown Thread),并將所有注冊的鉤子添加到其任務列表中。當 JVM 收到終止信號時:

  1. 停止所有用戶線程。
  2. 啟動關閉線程,按順序執(zhí)行鉤子任務。
  3. 等待所有鉤子執(zhí)行完畢或超時后退出。

鉤子的注冊與執(zhí)行

  • 注冊:通過Runtime.getRuntime().addShutdownHook(Thread)將線程添加到ApplicationShutdownHooks的靜態(tài)列表中。
  • 執(zhí)行:關閉線程按順序同步執(zhí)行系統(tǒng)級鉤子,異步執(zhí)行應用級鉤子,并等待所有線程完成。

關閉鉤子的觸發(fā)時機

  1. 主動調(diào)用:通過Runtime.exit()或System.exit()觸發(fā)。
  2. 信號捕獲:JVM 注冊信號處理器(如INT、TERM),捕獲kill命令發(fā)送的信號后觸發(fā)。

示例代碼(捕獲信號):

public class SignalHandlerTest implements SignalHandler {
    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> 
            System.out.println("關閉鉤子正在運行...")));

        SignalHandler handler = new SignalHandlerTest();
        Signal.handle(new Signal("INT"), handler);  // 捕獲 Ctrl+C
        Signal.handle(new Signal("TERM"), handler); // 捕獲 kill 命令

        while (true) {
            System.out.println("主線程運行中...");
            Thread.sleep(2000);
        }
    }

    @Override
    public void handle(Signal signal) {
        System.out.println("接收到信號:" + signal.getName() + "-" + signal.getNumber());
        System.exit(0);
    }
}

輸出示例:

主線程運行中...
主線程運行中...
^C接收到信號:INT-2
關閉鉤子正在運行...

信號處理與守護線程

  • 信號不可捕獲的情況:KILL(9)和QUIT(3)無法被捕獲。
  • 守護線程:JVM 在所有用戶線程結束后自動退出,守護線程(如 GC 線程)不會阻止 JVM 退出。

總結

Java 的關閉鉤子機制覆蓋了大部分退出場景,但以下情況例外:

  • 使用kill -9強制終止進程時,鉤子不會執(zhí)行。
  • 信號處理需調(diào)用System.exit()確保進程退出。

通過合理使用關閉鉤子,可以實現(xiàn)資源釋放、服務優(yōu)雅關閉等關鍵功能。

責任編輯:武曉燕 來源: 程序猿技術充電站
相關推薦

2021-03-28 09:17:18

JVM場景鉤子函數(shù)

2021-01-19 10:35:49

JVM場景函數(shù)

2017-12-19 10:03:44

JavaLinux代碼

2024-12-24 08:03:56

2022-06-28 08:01:26

hook狀態(tài)管理state

2022-04-11 08:17:07

JVMJava進程

2022-07-24 09:46:48

優(yōu)雅停機代碼

2021-04-20 08:00:31

Redisson關閉訂單支付系統(tǒng)

2020-12-01 12:44:44

PythonHook鉤子函數(shù)

2025-01-13 06:00:00

Go語言gRPC

2023-12-20 10:04:45

線程池Java

2017-09-19 14:53:37

Java并發(fā)編程并發(fā)代碼設計

2009-04-09 17:22:23

Linuxshutdown系統(tǒng)

2025-03-20 06:48:55

性能優(yōu)化JDK

2025-03-26 00:55:00

2011-12-29 13:31:15

Java

2025-02-17 00:00:25

Java并發(fā)編程

2025-02-19 00:05:18

Java并發(fā)編程

2025-06-18 08:10:00

Java并發(fā)編程開發(fā)

2024-11-13 16:37:00

Java線程池
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: cao视频 | 四虎午夜剧场 | 国产精品国产三级国产aⅴ中文 | 成人av在线播放 | 午夜天堂精品久久久久 | 日韩在线播放第一页 | 日韩精品在线播放 | 香蕉av免费| 天天躁日日躁狠狠的躁天龙影院 | 日本精品视频在线观看 | 欧美精品一区免费 | 欧美精品一区二区三区在线播放 | 日韩在线观看 | 91av入口| 男人亚洲天堂 | 国产伦精品一区二区三区精品视频 | 欧美日韩三级视频 | 自拍在线 | 91免费在线 | 国产精品一区二区福利视频 | 欧美综合一区二区三区 | 日日摸夜夜添夜夜添特色大片 | 欧美午夜精品 | 久久国产区 | 成人动慢 | 亚洲国产欧美在线 | 二区视频 | 久草视频观看 | 97国产精品 | 亚洲另类自拍 | 国产综合av | 国产一区 在线视频 | 羞羞视频网站免费看 | 欧美精品成人一区二区三区四区 | 精品区 | 在线看一区二区三区 | 久久免费电影 | 在线观看视频91 | 成人蜜桃av| 精品在线一区 | 欧美成人在线免费 |