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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一起学并发编程 - 钩子函数(shutdownHook)

發布時間:2023/12/31 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一起学并发编程 - 钩子函数(shutdownHook) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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

<!-- more -->

用途

在Jboss,Jetty等容器中都可以看到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<Thread, Thread> 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(歡迎調戲)

總結

以上是生活随笔為你收集整理的一起学并发编程 - 钩子函数(shutdownHook)的全部內容,希望文章能夠幫你解決所遇到的問題。

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