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

哦,這就是Java的優雅停機?(實現及原理)

開發 后端
優雅停機? 這個名詞我是服的,如果拋開專業不談,多好的名詞啊!其實優雅停機,就是在要關閉服務之前,不是立馬全部關停,而是做好一些善后操作,比如:關閉線程、釋放連接資源等。

優雅停機? 這個名詞我是服的,如果拋開專業不談,多好的名詞啊!

其實優雅停機,就是在要關閉服務之前,不是立馬全部關停,而是做好一些善后操作,比如:關閉線程、釋放連接資源等。

再比如,就是不會讓調用方的請求處理了一增,一下就中斷了。而處理完本次后,再停止服務。

Java語言中,我們可以通過Runtime.getRuntime().addShutdownHook()方法來注冊鉤子,以保證程序平滑退出。(其他語言也類似)

來個栗子:

  1. public class ShutdownGraceFullTest { 
  2.  
  3.     /** 
  4.      * 使用線程池處理任務 
  5.      */ 
  6.     public static ExecutorService executorService = Executors.newCachedThreadPool(); 
  7.  
  8.     public static void main(String[] args) { 
  9.  
  10.         //假設有5個線程需要執行任務 
  11.         for(int i = 0; i < 5; i++){ 
  12.             final int id = i; 
  13.             Thread taski = new Thread(new Runnable() { 
  14.                 @Override 
  15.                 public void run() { 
  16.                     System.out.println(System.currentTimeMillis() + " : thread_" + id + " start..."); 
  17.                     try { 
  18.                         TimeUnit.SECONDS.sleep(id); 
  19.                     } catch (InterruptedException e) { 
  20.                         e.printStackTrace(); 
  21.                     } 
  22.                     System.out.println(System.currentTimeMillis() + " : thread_" + id + " finish!"); 
  23.                 } 
  24.             }); 
  25.             taski.setDaemon(true); 
  26.             executorService.submit(taski); 
  27.         } 
  28.  
  29.         // 添加一個鉤子處理未完任務 
  30.         Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
  31.             @Override 
  32.             public void run() { 
  33.  
  34.                 System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " No1 shutdown hooking..."); 
  35.                 boolean shutdown = true
  36.                 try { 
  37.                     executorService.shutdown(); 
  38.                     System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() +  " shutdown signal got, wait threadPool finish."); 
  39.                     executorService.awaitTermination(1500, TimeUnit.SECONDS); 
  40.                     System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() +  " all thread's done."); 
  41.                 } 
  42.                 catch (InterruptedException e) { 
  43.                     e.printStackTrace(); 
  44.                 } 
  45.                 System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " No1 shutdown done..."); 
  46.             } 
  47.         })); 
  48.  
  49.         // 多個關閉鉤子并發執行 
  50.         Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { 
  51.             @Override 
  52.             public void run() { 
  53.                 try { 
  54.                     System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " No2 shutdown hooking..."); 
  55.                     Thread.sleep(1000); 
  56.                 } catch (InterruptedException e) { 
  57.                     e.printStackTrace(); 
  58.                 } 
  59.                 System.out.println(System.currentTimeMillis() + " : " + Thread.currentThread().getName() + " No2 shutdown done..."); 
  60.             } 
  61.         })); 
  62.  
  63.         System.out.println("main method exit..."); 
  64.         // 故意調用jvm退出命令,發送關閉信號,否則正常情況下 jvm 會等待***一個非守護線程關閉才會退出 
  65.         System.exit(0); 
  66.     } 

運行結果如下:

哦,這就是Java的優雅停機?(實現及原理)

很明顯,確實是優雅了,雖然***收到了一關閉信號,但是仍然保證了任務的處理完成。很棒吧!

那么,在實際應用中是如何體現優雅停機呢?

  1. kill -15 pid 

通過該命令發送一個關閉信號給到jvm, 然后就開始執行 Shutdown Hook 了,你可以做很多:

  1. 關閉 socket 鏈接
  2. 清理臨時文件
  3. 發送消息通知給訂閱方,告知自己下線
  4. 將自己將要被銷毀的消息通知給子進程
  5. 各種資源的釋放
  6. ...

而在平時工作中,我們不乏看到很多運維同學,是這么干的:

  1. kill -9 pid 

如果這么干的話,jvm也無法了,kill -9 相當于一次系統宕機,系統斷電。這會給應用殺了個措手不及,沒有留給應用任何反應的機會。

所以,無論如何是優雅不起來了。

要優雅,是代碼

其中,線程池的關閉方式為:

  1. executorService.shutdown();  
  2. executorService.awaitTermination(1500, TimeUnit.SECONDS); 

ThreadPoolExecutor 在 shutdown 之后會變成 SHUTDOWN 狀態,無法接受新的任務,隨后等待正在執行的任務執行完成。意味著,shutdown 只是發出一個命令,至于有沒有關閉還是得看線程自己。

ThreadPoolExecutor 對于 shutdownNow 的處理則不太一樣,方法執行之后變成 STOP 狀態,并對執行中的線程調用 Thread.interrupt() 方法(但如果線程未處理中斷,則不會有任何事發生),所以并不代表“立刻關閉”。

shutdown() :啟動順序關閉,其中執行先前提交的任務,但不接受新任務。如果已經關閉,則調用沒有附加效果。此方法不等待先前提交的任務完成執行。

shutdownNow():嘗試停止所有正在執行的任務,停止等待任務的處理,并返回正在等待執行的任務的列表。當從此方法返回時,這些任務將從任務隊列中耗盡(刪除)。此方法不等待主動執行的任務終止。

executor.awaitTermination(this.awaitTerminationSeconds, TimeUnit.SECONDS)); 控制等待的時間,防止任務***期的運行(前面已經強調過了,即使是 shutdownNow 也不能保證線程一定停止運行)。

注意:

  • 虛擬機會對多個shutdownhook以未知的順序調用,都執行完后再退出。
  • 如果接收到 kill -15 pid 命令時,執行阻塞操作,可以做到等待任務執行完成之后再關閉 JVM。同時,也解釋了一些應用執行 kill -15 pid 無法退出的問題,如:中斷被阻塞了,或者hook運行了死循環代碼。

 

責任編輯:未麗燕 來源: 等你歸去來
相關推薦

2024-12-13 16:37:56

SpringBootJava

2025-03-11 00:55:00

Spring停機安全

2018-11-08 15:30:04

JavaScriptES6異步

2021-05-08 08:33:00

Rocketmq日志數據源

2015-07-21 10:24:02

Windows RT升級

2023-01-30 07:41:43

2014-01-02 14:04:42

2019-01-02 04:40:19

物聯網企業IOT

2021-09-03 10:44:42

ThreadLocalObject 數組

2016-01-12 17:01:45

Bootstrap原因

2015-07-27 10:56:02

2025-03-17 00:00:00

2020-02-17 15:55:22

Office 365

2024-03-18 14:06:00

停機Spring服務器

2024-04-24 09:47:36

2015-01-09 10:10:00

Linux

2020-07-17 19:31:19

PythonR編程

2015-09-19 13:45:27

2022-06-08 08:06:05

LinuxJVM內存

2022-11-21 16:10:31

奔馳可靠性排名
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品成人一区 | 国产在线精品一区二区三区 | 日本在线网站 | 国产欧美精品一区二区三区 | 中文字幕在线免费观看 | 日韩欧美精品一区 | 精品一区二区三区免费毛片 | 日韩精品免费一区 | 国产婷婷精品av在线 | 精产国产伦理一二三区 | 国产精品国产三级国产aⅴ无密码 | 国产欧美精品一区 | 国产精品久久9 | 亚洲免费精品 | 少妇久久久久 | 亚洲视频国产 | 极品粉嫩国产48尤物在线播放 | 成人黄色av网站 | 国产精品高潮呻吟久久aⅴ码 | 精品免费国产一区二区三区四区介绍 | 亚洲国产一区二区三区 | 色婷婷精品国产一区二区三区 | 欧美精品网 | 久久国产精品久久 | 午夜男人天堂 | 欧美精品日韩 | 免费黄视频网站 | 精品蜜桃一区二区三区 | 欧美日韩不卡 | 中文字幕一区二区三区在线视频 | 亚洲国产欧美日韩 | av日韩高清| 日韩精品1区2区 | 久久综合香蕉 | 国产视频中文字幕 | 日韩欧美一级片 | 日本人爽p大片免费看 | 亚洲高清免费观看 | 亚洲一区二区三区在线播放 | 日本淫视频| 久久成人18免费网站 |