国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

一起學并發編程 - 鉤子函數(shutdownHook)

qpal / 3283人閱讀

摘要:在退出時執行必要的挽救措施。在這種情況下,一旦被提供,等待一個進程終止指定的時間。如果進程在該時間限制內沒有終止,則通過發出或中的對等方強制終止進程。所以有可能這是在中途執行時發生的。

shutdownHook是一種特殊的結構,它允許開發人員插入JVM關閉時執行的一段代碼。這種情況在我們需要做特殊清理操作的情況下很有用

用途

JbossJetty等容器中都可以看到shutdownHook的身影,例如在服務優雅下線一文中的spring-boot-starter-actuator就會觸發shutdownHook...

Application正常退出,在退出時執行特定的業務邏輯,或者關閉資源等操作。

虛擬機非正常退出,比如用戶按下ctrl+c、OOM宕機、操作系統關閉(kill pid)等。在退出時執行必要的挽救措施。

用法

正常退出

public class ShutdownHook {

    public static void main(String[] args) throws InterruptedException {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try (FileWriter fw = new FileWriter("hook.log")) {
                // 假設記錄日志/或者發送消息
                fw.write("完成銷毀操作,回收內存! " + (new Date()).toString());
                System.out.println("退出程序...");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }));
        IntStream.range(0, 10).forEach(i -> {
            try {
                System.out.println("正在工作...");
                Thread.sleep(2_000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    }
}

當我們運行上面的代碼時,會看到在完成main方法的執行時JVM調用shutdownHook

正在工作...
...
正在工作...
退出程序...

kill pid方式

注意事項

雖然編寫一個shutdownHook很簡單,但是需要了解shutdownHook后面的內部部件才能正確使用。因此,在后續中,將探討shutdownHook設計背后的一些陷阱

應用程序無法保證shutdownHook總是運行的

如JVM由于某些內部錯誤而崩潰,或(Unix / Linux中的kill -9)或TerminateProcess(Windows)),那么應用程序需要立即終止而不會甚至等待任何清理活動。除了上述之外,還可以通過調用Runime.halt()方法來終止JVM,而阻止shutdownHook運行。

shutdownHook可以在完成前強行停止

雖然shutdownHook開始執行,但是在操作系統關閉的情況下,任然可以在完成之前終止它。在這種情況下,一旦SIGTERM被提供,O/S等待一個進程終止指定的時間。如果進程在該時間限制內沒有終止,則O/S通過發出SIGTERM(或Windows中的對等方)強制終止進程。所以有可能這是在shutdownHook中途執行時發生的。

因此,建議謹慎地編寫shutdownHook,確保它們快速完成,并且不會造成死鎖等情況。另外特別注意的是,不應該執行長時間計算或等待用戶I/O操作在鉤子。

可以有多個shutdownHook,但其執行順序無法保證

public void addShutdownHook(Thread hook) {
    SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        sm.checkPermission(new RuntimePermission("shutdownHooks"));
    }
    ApplicationShutdownHooks.add(hook);
}
class ApplicationShutdownHooks {
    /* The set of registered hooks */
    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);
    }
}

通過源碼發現,可以注冊多個shutdownHook。但是因為它是存儲在IdentityHashMap中的,JVM并不能保證其執行順序。但是可以同時執行所有的shutdownHook

關閉順序開始后,無法注冊/取消注冊shutdownHook

一旦關閉順序是由JVM發起的,將不在允許添加或刪除任何現有的shutdownHook,否則拋出IllegalStateException異常。

關閉順序開始后,只能由Runtime.halt()停止

關閉順序開始后,只能通過Runtime.halt()(強制終止JVM),可以停止關閉順序的執行(外部影響除外,如SIGKILL)。

使用shutdownHook需要安全權限

如果我們使用Java Security Managers,則執行添加/刪除shutdownHook的代碼需要在運行時具有shutdownHooks權限。否則會導致SecurityException

參考:http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Runtime.html#addShutdownHook(java.lang.Thread) "官方文檔")

- 說點什么

全文代碼:https://gitee.com/battcn/battcn-concurent/tree/master/Chapter1-1/battcn-thread/src/main/java/com/battcn/chapter10

個人QQ:1837307557

battcn開源群(適合新手):391619659

微信公眾號:battcn(歡迎調戲)

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67730.html

相關文章

  • 和少婦白潔一起JavaScript之Async/Await

    摘要:匿名函數是我們喜歡的一個重要原因,也是,它們分別消除了很多代碼細節上需要命名變量名或函數名的需要。這個匿名函數內,有更多的操作,根據的結果針對目錄和文件做了不同處理,而且有遞歸。 能和微博上的 @響馬 (fibjs作者)掰扯這個問題是我的榮幸。 事情緣起于知乎上的一個熱貼,諸神都發表了意見: https://www.zhihu.com/questio... 這一篇不是要說明白什么是as...

    Bryan 評論0 收藏0
  • 一起并發編程 - 處理異常中止的線程

    摘要:在之前,不能為線程單獨設置或指定一個默認的,為了設置,需要繼承并覆寫方法。幸運的是后線程提供了一個方法,用來捕獲并處理因線程中拋出的未知異常,以避免程序終止。 在單線程的開發過程中,通常采用try-catch的方式進行異常捕獲,但是這種方式在多線程環境中會顯得無能為力,而且還有可能導致一些問題的出現,比如發生異常的時候不能及時回收系統資源,或者無法及時關閉當前的連接... 概述 Ja...

    zacklee 評論0 收藏0
  • 一起并發編程 - synchronized詳解

    摘要:每個對象只有一個鎖與之相關聯。實現同步則是以系統開銷作為代價,甚至可能造成死鎖,所以盡量避免濫用。這種機制確保了同一時刻該類實例,所有聲明為的函數中只有一個方法處于可執行狀態,從而有效避免了類成員變量訪問沖突。 synchronized是JAVA語言的一個關鍵字,使用 synchronized 來修飾方法或代碼塊的時候,能夠保證多個線程中最多只有一個線程執行該段代碼 ... 概述 ...

    acrazing 評論0 收藏0
  • 一起并發編程 - 守護線程

    摘要:的作用是為其他線程的運行提供服務,比如說線程。在某些平臺上,指定一個較高的參數值可能使線程在拋出之前達到較大的遞歸深度。參數的值與最大遞歸深度和并發程度之間的關系細節與平臺有關。 今天研究了下Java線程基礎知識,發現以前太多知識知識略略帶過了,比較說Java的線程機制,在Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護線程),以及構造器中的s...

    junnplus 評論0 收藏0
  • 一起并發編程 - 等待與通知

    摘要:如果有其它線程調用了相同對象的方法,那么處于該對象的等待池中的線程就會全部進入該對象的鎖池中,從新爭奪鎖的擁有權。 wait,notify 和 notifyAll,這些在多線程中被經常用到的保留關鍵字,在實際開發的時候很多時候卻并沒有被大家重視,而本文則是對這些關鍵字的使用進行描述。 存在即合理 在java中,每個對象都有兩個池,鎖池(monitor)和等待池(waitset),每個...

    Meathill 評論0 收藏0

發表評論

0條評論

qpal

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<