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

設計Java應用程序的平滑停止

開發(fā) 后端
程序的退出就像關機一樣,我們希望關機時平滑關機,保證所有應用程序的數(shù)據(jù)都保存了。就像現(xiàn)在在寫得blog,希望關機的時候能被保存好到草稿箱里。

Java應用程序退出的觸發(fā)機制有:

  1. 自動結束:應用沒有存活線程或只有后臺線程時;
  2. System.exit(0);
  3. kill 或 ctrl+C;
  4. kill -9 強制退出;

如何做到應用程序平滑停止

程序的退出就像關機一樣,我們希望關機時平滑關機,保證所有應用程序的數(shù)據(jù)都保存了。就像現(xiàn)在在寫得blog,希望關機的時候能被保存好到草稿箱里。

我們的的Java程序中經(jīng)常有一種常駐的任務或服務,如消息消費端、服務提供者,我們期望停止也是平滑的不會出現(xiàn)事務執(zhí)行到一半產(chǎn)生臟數(shù)據(jù)。

 

java對這塊的支持是通過鉤子線程實現(xiàn)。每個Java進程都可以注冊鉤子線程,鉤子線程程在程序退出的前被執(zhí)行(kill -9強制退出除外)。注冊鉤子線程代碼如下:

  1. Runtime.getRuntime().addShutdownHook(t); 

我們可以在鉤子線程里做一些善后數(shù)據(jù)清理等事情,以保證程序是平滑退出的。

一般服務或框架運行都要考慮其生命周期:

如spring容器的context.stop()方法。

再如線程池ExecutorService的shutdown方法,它會保證不接受新任務,并把未執(zhí)行完的任務做完。

 

我們再設計服務的時候也要考慮到停止時的stop方法,以便于退出時由鉤子線程調用。

注冊了鉤子線程后,程序收到退出信號后,會保持程序運行,直到鉤子線程執(zhí)行完畢,才把程序的所有線程停止并退出,下面示例代碼可以說明這一點:

  1. public class ShutDownTest {  
  2.  
  3.     public static void main(String[] args) {  
  4.         //注冊***個鉤子  
  5.         Runtime.getRuntime().addShutdownHook(new Thread() {  
  6.  
  7.             public void run() {  
  8.                 try {  
  9.                     Thread.currentThread().sleep(5000);  
  10.                 } catch (InterruptedException e) {  
  11.                     e.printStackTrace();  
  12.                 }  
  13.                 System.out.println("clean task1 completed.");  
  14.             }  
  15.         });  
  16.         //注冊第二個鉤子  
  17.         Runtime.getRuntime().addShutdownHook(new Thread() {  
  18.  
  19.             public void run() {  
  20.                 try {  
  21.                     Thread.currentThread().sleep(10000);  
  22.                 } catch (InterruptedException e) {  
  23.                     e.printStackTrace();  
  24.                 }  
  25.                 System.out.println("clean task2 completed");  
  26.             }  
  27.         });  
  28.         //啟動子線程  
  29.         new Thread() {  
  30.  
  31.             public void run() {  
  32.                 while (true) {  
  33.                     try {  
  34.                         Thread.currentThread().sleep(1000);  
  35.                         System.out.println("sub thread is running");  
  36.                     } catch (InterruptedException e) {  
  37.                         e.printStackTrace();  
  38.                     }  
  39.                 }  
  40.             }  
  41.         }.start();  
  42.         //程序退出  
  43.         System.exit(0);  
  44.     }  
  45.  

程序輸出:

  1. sub thread is running  
  2. sub thread is running  
  3. sub thread is running  
  4. sub thread is running  
  5. clean task1 completed.  
  6. sub thread is running  
  7. sub thread is running  
  8. sub thread is running  
  9. sub thread is running  
  10. sub thread is running  
  11. clean task2 completed 

注意點:鉤子線程里只處理善后,目標是盡可能快的退出且不保證有臟數(shù)據(jù)。如果鉤子線程里做過多事情,或者發(fā)生阻塞,那么可能出現(xiàn)kill失效,程序不能退出的情況,這是需要強制退出。

如以下程序會導致kill失效,需要強制退出,因為鉤子線程阻塞了:

  1. public class ShutDownTest {  
  2.  
  3.     public static void main(String[] args) {  
  4.         //注冊鉤子  
  5.         Runtime.getRuntime().addShutdownHook(new Thread() {  
  6.             public void run() {  
  7.                 synchronized (ShutdownFileTest.class) {  
  8.                     try {  
  9.                         ShutdownFileTest.class.wait();  
  10.                     } catch (InterruptedException e) {  
  11.                         e.printStackTrace();  
  12.                     }  
  13.                 }  
  14.             }  
  15.         });  
  16.         //啟動子線程  
  17.         new Thread() {  
  18.             public void run() {  
  19.                 while (true) {  
  20.                     try {  
  21.                         Thread.currentThread().sleep(1000);  
  22.                         System.out.println("sub thread is running");  
  23.                     } catch (InterruptedException e) {  
  24.                         e.printStackTrace();  
  25.                     }  
  26.                 }  
  27.             }  
  28.         }.start();  
  29.        System.exit(0);  
  30.        }  
  31.  

程序退出機制選擇

觸發(fā)程序退出的在前面已經(jīng)提到過,但是為了停止方便、安全和優(yōu)雅,一般我們推薦幾種操控性更強的退出機制。常見的推薦機制有以下幾種:

1.kill

在linux里用的比較多,向進程發(fā)送退出信號,java進程收到后平滑退出。

2.shutdownfile

系統(tǒng)創(chuàng)建一個shutdown file.并監(jiān)聽shutdown file是否存在。如果發(fā)現(xiàn)shutdown file不存在了,那么調用System.exit,將程序退出。

如果期望只有特定的人才能終止該程序,那么你可以給文件設定權限,這樣就只有特定的人可以終止程序。

以下代碼是個簡單的例子:

  1. import java.io.File;  
  2. import java.io.IOException;  
  3.  
  4. public class ShutdownFileTest {  
  5.  
  6.     public static void main(String[] args) {  
  7.         // 啟動子線程  
  8.         new Thread() {  
  9.  
  10.             public void run() {  
  11.                 while (true) {  
  12.                     try {  
  13.                         Thread.currentThread().sleep(1000);  
  14.                         System.out.println("sub thread is running");  
  15.                     } catch (InterruptedException e) {  
  16.                         e.printStackTrace();  
  17.                     }  
  18.                 }  
  19.             }  
  20.         }.start();  
  21.           
  22.         //啟動shutdownfile監(jiān)聽線程  
  23.         new Thread() {  
  24.  
  25.             public void run() {  
  26.                 File shutDownFile = new File("a.shutdown");  
  27.                 // create shut down file  
  28.                 if (!shutDownFile.exists()) {  
  29.                     try {  
  30.                         shutDownFile.createNewFile();  
  31.                     } catch (IOException e) {  
  32.                         e.printStackTrace();  
  33.                     }  
  34.                 }  
  35.                 // watch for file deleted then shutdown   
  36.                 while (true) {  
  37.                     try {  
  38.                         if (shutDownFile.exists()) {  
  39.                             Thread.currentThread().sleep(1000);  
  40.                         } else {  
  41.                             System.exit(0);  
  42.                         }  
  43.                     } catch (InterruptedException e) {  
  44.                         e.printStackTrace();  
  45.                     }  
  46.                 }  
  47.             }  
  48.         }.start();  
  49.     }  
  50.  

3.打開一個端口,監(jiān)聽端口里的命令,收到命令后調用System.exit。

這個似乎不常見,也比較麻煩。

4.JMX

通過JMX的mbean遠程控制來實現(xiàn)。

在這個鏈接里有看到例子:how-to-stop-java-process-gracefully

原文鏈接:http://singleant.iteye.com/blog/1441219

【編輯推薦】

  1. 深入Java探索:Java內存區(qū)域
  2. 同一段程序在Java和C中的不同結果
  3. Java中Runnable和Thread的區(qū)別
  4. Java對存儲過程的調用方法
  5. Java初學者都必須理解的六大問題
責任編輯:林師授 來源: singleant的博客
相關推薦

2023-08-14 08:03:25

前端應用程序Typescript

2020-12-28 14:40:47

云計算云應用SaaS

2011-10-25 10:24:03

Windows Pho

2010-06-12 16:59:45

UML設計

2011-04-11 14:45:41

性能設計官方文檔Android

2015-01-06 09:59:59

云應用程序Java開發(fā)SQL

2009-09-03 08:46:55

UML類圖Java

2025-03-19 09:04:39

2012-11-15 10:18:11

IBMdw

2012-02-15 14:39:55

GNOME 3

2010-03-04 10:11:17

Android手機系統(tǒng)

2022-05-04 23:08:36

標準Go應用程序

2010-08-12 15:59:23

Flex應用程序

2020-03-27 09:20:00

單頁應用程序網(wǎng)頁設計SPAs

2012-04-04 22:10:14

UI

2011-04-01 11:01:02

應用程序BlackBerryJava

2012-06-07 09:15:14

ibmdw

2012-05-29 10:04:08

2009-09-27 10:37:01

Java應用程序Hibernate

2010-09-06 14:33:46

AndroidJava
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲一级毛片 | 亚洲精品乱码8久久久久久日本 | 午夜av电影 | 精品视频一区二区三区在线观看 | 国产精品亚洲第一区在线暖暖韩国 | www精品美女久久久tv | 在线成人精品视频 | 国产一区二区视频在线 | 久久久久九九九女人毛片 | 久久a久久| 91精品国模一区二区三区 | 国产免费视频 | 日韩欧美网 | 亚洲福利一区 | 成人在线中文字幕 | 国产一区不卡 | 亚洲 日本 欧美 中文幕 | 亚洲视频一区二区三区 | 久国产| 国产ts人妖一区二区三区 | 久久久久一区二区三区四区 | 91精品国产欧美一区二区成人 | 中文字幕乱码一区二区三区 | 伊人久久在线 | 韩日一区二区三区 | 国产精品18hdxxxⅹ在线 | 日本免费视频在线观看 | 在线视频一区二区三区 | 亚洲激情在线观看 | 久久久免费观看视频 | 青青久久av北条麻妃海外网 | 人人人人干 | 视频精品一区二区三区 | 久久久久久久久久久福利观看 | 国产一区二区三区网站 | 国产黄色大片网站 | 天天干天天玩天天操 | 一道本不卡视频 | 久久在看| 久久久久久久一区 | 三级视频在线观看电影 |