成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何使用鉤子優雅的關閉JVM?

云計算 虛擬化
程序的啟動很簡單,啟動的時候通常會做一些預加載資源的操作。但是有時候關閉的時候,啟動的時候預加載的資源并沒有完全清理干凈,因此可以使用鉤子函數來完成。

[[390011]]

前言

1、基本概述

程序的啟動很簡單,啟動的時候通常會做一些預加載資源的操作。但是有時候關閉的時候,啟動的時候預加載的資源并沒有完全清理干凈,因此可以使用鉤子函數來完成。

2、JVM關閉的場景分類

直接看一張圖吧,本圖來自博客園的BarryWang,特在此說明。

從上面可以看到,JVM關閉主要分為了三類,第一種是正常的關閉,第二種是異常關閉的情況,第三種是強制關閉的情況。對于前兩種方式我們可以使用鉤子函數優雅的關閉,但是強制關閉的時候鉤子函數并不起作用。

有了這些概念,我們直接使用一個案例進行演示,再進行分析。

一、代碼演示鉤子函數

1、JVM正常關閉

直接看代碼吧,

  1. public class Test { 
  2.  public void start(){ 
  3.   Runtime.getRuntime().addShutdownHook(new Thread(()->  
  4.     System.out.println("鉤子函數被執行,可以在這里關閉資源"
  5.   )); 
  6.  } 
  7.  public static void main(String[] args) throws Exception{ 
  8.   new Test().start(); 
  9.   System.out.println("主應用程序在執行"); 
  10.  } 
  11. //控制臺輸出 
  12. //主應用程序在執行 
  13. //鉤子函數被執行,可以在這里關閉資源 

看控制臺打印,可以發現,主應用程序執行完之后就會調用鉤子函數,接下來就會正式的關閉JVM。

2、異常關閉

還是直接看代碼演示,這里我們演示異常關閉的第二種OOM的情況,我們可以先設置堆的大小為20M,然后在代碼中創建一個500M的對象,這樣就會OOM。參數是-Xmx20M;

  1. public class Test { 
  2.  public void start(){ 
  3.   Runtime.getRuntime().addShutdownHook(new Thread(()->  
  4.     System.out.println("鉤子函數被執行,可以在這里關閉資源"
  5.   )); 
  6.  } 
  7.  public static void main(String[] args) throws Exception{ 
  8.   new Test().start(); 
  9.   System.out.println("主應用程序在執行"); 
  10.   Runtime.getRuntime().halt(1); 
  11.   byte[] b = new byte[500*1024*1024]; 
  12.  } 
  13. //控制臺輸出 
  14. //主應用程序在執行 
  15. //鉤子函數被執行,可以在這里關閉資源 

從控制臺可以看出,鉤子函數在異常關閉的時候依然會被調用。

3、強制關閉

這里我們使用Runtime.getRuntime().halt()來演示強勢關閉。這個方法和System.exit的區別是,System.exit會執行鉤子函數,但是Runtime.getRuntime().halt()不會。

  1. public class Test { 
  2.  public void start(){ 
  3.   Runtime.getRuntime().addShutdownHook(new Thread(()->  
  4.     System.out.println("鉤子函數被執行,可以在這里關閉資源"
  5.   )); 
  6.  } 
  7.  public static void main(String[] args) throws Exception{ 
  8.   new Test().start(); 
  9.   System.out.println("主應用程序在執行"); 
  10.   Runtime.getRuntime().halt(1); 
  11.  } 
  12. //控制臺輸出 
  13. //主應用程序在執行 

從上面代碼的輸出可以看出,調用了Runtime.getRuntime().halt(1)就會強制關閉JVM,鉤子函數來不及執行就關閉了。而使用System.exit依然會執行。所以一般使用System.exit來關閉JVM。

4、移除鉤子函數

上面演示了鉤子函數的作用,有時候我們想移除也比較簡單。

  1. public class Test { 
  2.  public static void main(String[] args) throws Exception{ 
  3.   //new Test().start(); 
  4.   Thread willNotRun = new Thread(() ->  
  5.    System.out.println("Won't run!")); 
  6.   Runtime.getRuntime().addShutdownHook(willNotRun); 
  7.   System.out.println("主應用程序在執行"); 
  8.   Runtime.getRuntime().removeShutdownHook(willNotRun); 
  9.  } 
  10. //控制臺輸出 
  11. //主應用程序在執行 

OK,鉤子函數的基本操作就寫到這,使用起來比較簡單,不過我之前看過Spring的啟動流程,所以又去那個啟動流程看了一波,發現也使用到了鉤子函數。

二、典型應用場景

1、Spring使用

Spring在關閉上下文的時候,可以使用鉤子函數來關閉殘留的資源。方法是使用ApplicationContext注冊一個鉤子函數即可。

  1. ApplicationContext.registerShutdownHook(); 
  2. //上面的這句代碼可以分析進去看看 
  3. public void registerShutdownHook() { 
  4.     if (this.shutdownHook == null) { 
  5.       this.shutdownHook = new Thread() { 
  6.         @Override 
  7.         public void run() { 
  8.           //Spring正常關閉 
  9.           doClose(); 
  10.         } 
  11.       }; 
  12.       //調用鉤子函數關閉殘留資源 
  13.       Runtime.getRuntime().addShutdownHook(this.shutdownHook); 
  14.     } 

從源碼可以看出,Spring其實也是調用了Java的鉤子函數進行關閉的。

2、其他使用

我在很多博客中也看到了spark和hadoop的關閉,由于我沒看過源碼,所以這里我說一下結論,對于其他的使用場景,基本上也是調用了Java的鉤子函數來執行的。

結論

在關閉JVM的時候,我們可以封裝鉤子函數去優雅的關閉線程。不過在使用的時候還需要注意以下幾個方面:

1、鉤子函數本質是個線程

多個鉤子會并發執行,JVM并不保證它們的執行順序;因此最好是在一個鉤子中執行一系列操作。

2、鉤子中不能再新建鉤子

在關閉鉤子中,不能執行注冊、移除鉤子的操作,否則JVM拋出 IllegalStateException。也不能使用System.exit(),前面提到System.exit()會觸發鉤子函數的執行,但是Runtime.halt()可以,因為Runtime.halt()可以強制關閉。

3、鉤子里最好不要有耗時操作

鉤子函數主要用于關閉殘留資源,因此不要有一些耗時的操作。

 

OK,先寫到這。

本文轉載自微信公眾號「愚公要移山」,可以通過以下二維碼關注。轉載本文請聯系愚公要移山公眾號。

 

責任編輯:武曉燕 來源: 愚公要移山
相關推薦

2021-01-19 10:35:49

JVM場景函數

2025-02-12 00:21:44

Java并發編程

2022-04-11 08:17:07

JVMJava進程

2021-04-20 08:00:31

Redisson關閉訂單支付系統

2022-07-24 09:46:48

優雅停機代碼

2017-12-19 10:03:44

JavaLinux代碼

2024-11-13 16:37:00

Java線程池

2015-11-26 10:53:45

LinuxWindowsMac OS

2017-07-26 11:32:50

NETRabbitMQ系統集成

2021-12-06 09:57:25

容器Linux信號

2023-06-16 09:08:39

ReactContextRFC

2022-09-14 08:16:48

裝飾器模式對象

2022-09-08 07:32:56

JDK7程序管理

2025-01-13 06:00:00

Go語言gRPC

2022-06-02 10:02:47

Kubectl更新應用Linux

2023-06-28 08:25:14

事務SQL語句

2022-10-27 11:23:26

GoFrame共享變量

2019-11-18 15:50:11

AjaxJavascript前端

2022-02-28 09:19:12

MDK芯片軟件

2019-11-15 09:58:04

LinuxAsciinemapython
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕精品一区二区三区精品 | 久久这里只有精品首页 | 免费精品视频在线观看 | 99久久婷婷国产综合精品电影 | 欧美精品在欧美一区二区少妇 | 国产一级淫片a直接免费看 免费a网站 | 久久久久国产一区二区三区 | 欧美精品一区二区三区蜜桃视频 | 久久这里只有精品首页 | 中文字幕一区在线观看视频 | 欧美日韩免费 | 欧美视频一区二区三区 | 午夜在线小视频 | 在线成人www免费观看视频 | 亚洲激情在线视频 | 毛片视频免费 | 一级黄色片网站 | 欧美视频网 | 欧美一区二 | 欧美精品一区二区在线观看 | 精品国产成人 | 日韩在线免费视频 | 激情六月丁香 | 欧美日韩国产一区二区三区 | 91在线一区| 亚洲精品久久久久久久久久吃药 | 国产美女视频黄 | 在线免费看黄 | 久久99精品国产自在现线小黄鸭 | 最新中文字幕第一页视频 | 不卡一二三区 | 久久久久se| 欧美日韩一二区 | 古装三级在线播放 | 在线色网站 | 国产不卡一区 | 一区二区三区亚洲视频 | 97在线超碰 | 国产一区二区三区四区hd | av一二三四| 久在线|