日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 钩子_面试官: 什么是 Hook (钩子) 线程以及应用场景?

發布時間:2025/3/12 数据库 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 钩子_面试官: 什么是 Hook (钩子) 线程以及应用场景? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Hook 線程介紹

通常情況下,我們可以向應用程序注入一個或多個 Hook (鉤子) 線程,這樣,在程序即將退出的時候,也就是 JVM 程序即將退出的時候,Hook 線程就會被啟動執行。

先看一段示例代碼:

①:為應用程序注入一個鉤子(Hook)線程,線程中,打印了相關日志,包括正在運行以及退出的日志;

②:再次注入一個同樣邏輯的鉤子(Hook)線程;

③:主線程執行結束,打印日志;

運行這段代碼,來驗證一下:

從打印日志看到,當主線程執行結束,也就是 JVM 進程即將退出的時候,注入的兩個 Hook 線程都被啟動并打印相關日志。

二、Hook 線程的應用場景&注意事項

2.1 應用場景

上面我們已經知道了, Hook 線程能夠在 JVM 程序退出的時候被啟動且執行,那么,我們能夠通過這種特性,做點什么呢?

羅列一些常見應用場景:

防止程序重復執行,具體實現可以在程序啟動時,校驗是否已經生成 lock 文件,如果已經生成,則退出程序,如果未生成,則生成 lock 文件,程序正常執行,最后再注入 Hook 線程,這樣在 JVM 退出的時候,線程中再將 lock 文件刪除掉;

PS: 這種防止程序重復執行的策略,也被應用于 Mysql 服務器,zookeeper, kafka 等系統中。

Hook 線程中也可以執行一些資源釋放的操作,比如關閉數據庫連接,Socket 連接等。

2.2 注意事項

Hook 線程只有在正確接收到退出信號時,才能被正確執行,如果你是通過 kill -9這種方式,強制殺死的進程,那么抱歉,進程是不會去執行 Hook 線程的,為什么呢?你想啊,它自己都被強制干掉了,哪里還管的上別人呢?

請不要在 Hook 線程中執行一些耗時的操作,這樣會導致程序長時間不能退出。

三、Hook 線程防應用重啟實戰

針對上面防應用重啟的場景,利用 Hook 線程,我們來實戰一下,貼上代碼:

import java.io.File;

import java.io.IOException;

import java.util.concurrent.TimeUnit;

/**

* @author 小澤java

* @date 2019/4/15

* @time 下午3:56

* @discription

**/

public class PreventDuplicated {

/** .lock 文件存放路徑 */

private static final String LOCK_FILE_PATH = "./";

/** .lock 文件名稱 */

private static final String LOCK_FILE_NAME = ".lock";

public static void main(String[] args) {

// 校驗 .lock 文件是否已經存在

checkLockFile();

// 注入 Hook 線程

addShutdownHook();

// 模擬程序一直運行

for (;;) {

try {

TimeUnit.SECONDS.sleep(1);

System.out.println("The program is running ...");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

/**

* 注入 Hook 線程

*/

private static void addShutdownHook() {

Runtime.getRuntime().addShutdownHook(new Thread(() -> {

// 接受到了退出信號

System.out.println("The program received kill signal.");

// 刪除 .lock 文件

deleteLockFile();

}));

}

/**

* 校驗 .lock 文件是否已經存在

*/

private static void checkLockFile() {

if (isLockFileExisted()) {

// .lock 文件已存在, 拋出異常, 退出程序

throw new RuntimeException("The program already running.");

}

// 不存在,則創建 .lock 文件

createLockFile();

}

/**

* 創建 .lock 文件

*/

private static void createLockFile() {

File file = new File(LOCK_FILE_PATH + LOCK_FILE_NAME);

try {

file.createNewFile();

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* .lock 文件 是否存在

* @return

*/

private static boolean isLockFileExisted() {

File file = new File(LOCK_FILE_PATH + LOCK_FILE_NAME);

return file.exists();

}

/**

* 刪除 .lock 文件

*/

private static void deleteLockFile() {

File file = new File(LOCK_FILE_PATH + LOCK_FILE_NAME);

file.delete();

}

}

運行程序,控制臺輸出如下:

程序一直運行中,再來看下 .lock 文件是否生成:

文件生成成功,接下來,我們再次運行程序,看看是否能夠重復啟動:

可以看到,無法重復運行程序,且拋出了 The program already running. 的運行時異常。接下來,通過 kill pid 或者 kill -l pid 命令來結束進程:

程序在即將退出的時候,啟動了 Hook 線程,在看下 .lock 文件是否已被刪除:

到此,Hook 線程代碼實戰部分結束了。

總結

以上是生活随笔為你收集整理的mysql 钩子_面试官: 什么是 Hook (钩子) 线程以及应用场景?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。