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

資訊專欄INFORMATION COLUMN

一起學(xué)并發(fā)編程 - 鉤子函數(shù)(shutdownHook)

qpal / 3287人閱讀

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

shutdownHook是一種特殊的結(jié)構(gòu),它允許開發(fā)人員插入JVM關(guān)閉時執(zhí)行的一段代碼。這種情況在我們需要做特殊清理操作的情況下很有用

用途

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

Application正常退出,在退出時執(zhí)行特定的業(yè)務(wù)邏輯,或者關(guān)閉資源等操作。

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

用法

正常退出

public class ShutdownHook {

    public static void main(String[] args) throws InterruptedException {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try (FileWriter fw = new FileWriter("hook.log")) {
                // 假設(shè)記錄日志/或者發(fā)送消息
                fw.write("完成銷毀操作,回收內(nèi)存! " + (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();
            }
        });
    }
}

當(dāng)我們運(yùn)行上面的代碼時,會看到在完成main方法的執(zhí)行時JVM調(diào)用shutdownHook

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

kill pid方式

注意事項

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

應(yīng)用程序無法保證shutdownHook總是運(yùn)行的

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

shutdownHook可以在完成前強(qiáng)行停止

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

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

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

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

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

關(guān)閉順序開始后,無法注冊/取消注冊shutdownHook

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

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

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

使用shutdownHook需要安全權(quán)限

如果我們使用Java Security Managers,則執(zhí)行添加/刪除shutdownHook的代碼需要在運(yùn)行時具有shutdownHooks權(quán)限。否則會導(dǎo)致SecurityException

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

- 說點(diǎn)什么

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

個人QQ:1837307557

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

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

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/67730.html

相關(guān)文章

  • 和少婦白潔一起學(xué)JavaScript之Async/Await

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

    Bryan 評論0 收藏0
  • 一起學(xué)并發(fā)編程 - 處理異常中止的線程

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

    zacklee 評論0 收藏0
  • 一起學(xué)并發(fā)編程 - synchronized詳解

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

    acrazing 評論0 收藏0
  • 一起學(xué)并發(fā)編程 - 守護(hù)線程

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

    junnplus 評論0 收藏0
  • 一起學(xué)并發(fā)編程 - 等待與通知

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

    Meathill 評論0 收藏0

發(fā)表評論

0條評論

qpal

|高級講師

TA的文章

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