亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

面試官: 什么是 Hook (鉤子) 線程以及應用場景?

發布時間:2020-07-27 23:11:47 來源:網絡 閱讀:911 作者:Java月亮呀 欄目:編程語言

一、Hook 線程介紹

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

先看一段示例代碼:

面試官: 什么是 Hook (鉤子) 線程以及應用場景?

:為應用程序注入一個鉤子(Hook)線程,線程中,打印了相關日志,包括正在運行以及退出的日志;
:再次注入一個同樣邏輯的鉤子(Hook)線程;
:主線程執行結束,打印日志;

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

面試官: 什么是 Hook (鉤子) 線程以及應用場景?
從打印日志看到,當主線程執行結束,也就是 JVM 進程即將退出的時候,注入的兩個 Hook 線程都被啟動并打印相關日志。

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

2.1 應用場景

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

羅列一些常見應用場景:

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

面試官: 什么是 Hook (鉤子) 線程以及應用場景?

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();
 }
}
</pre>

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

面試官: 什么是 Hook (鉤子) 線程以及應用場景?

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

面試官: 什么是 Hook (鉤子) 線程以及應用場景?

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

面試官: 什么是 Hook (鉤子) 線程以及應用場景?

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

面試官: 什么是 Hook (鉤子) 線程以及應用場景?

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

面試官: 什么是 Hook (鉤子) 線程以及應用場景?

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

南汇区| 桑日县| 屯留县| 澎湖县| 印江| 红原县| 天等县| 民县| 昌图县| 鹤庆县| 敖汉旗| 乌什县| 蚌埠市| 资兴市| 桃江县| 新源县| 海城市| 商洛市| 闽清县| 侯马市| 大新县| 山丹县| 萨嘎县| 津南区| 永靖县| 桂林市| 巴里| 南江县| 峨山| 迁安市| 剑川县| 米易县| 滁州市| 沛县| 呼玛县| 彭水| 佛学| 喀什市| 新昌县| 饶阳县| 长葛市|