寫了一些服務器程序,監聽端口,連接數據庫,諸如此類的,通過命令行運行。可是程序的退出是個大問題,因為是命令行程序,所以也沒有什么退出的按鈕給用戶去點,關閉程序時,一般是關閉控制台窗口。
最近遇到麻煩了,關閉控制台窗口以后,程序實際沒有退出,端口依然被監聽,和數據庫的連接依然保持。。。再運行程序,報錯:端口被占用
如果能知道控制台窗口被關閉的事件,那就解決我的難題了,找了好久,終於找到了這個解決辦法
一個完整的Java應用程序,通常至少要有一個應用程序的結束點。對於一般程序來說,系統開發者根據需要和個人的偏好,會在程序結束位置,通過添加System.exit(0),或System.out(-1),來結束程序,或不加這些指令,讓程序自然運行到結束。
如:下列典型代碼
/** * This application is to demo how an applcation end */ public class Test { public Test() { } public static void main(String[] args) { Test test1 = new Test(); System.out.println("hello world"); System.exit(0);//也可以不寫這句代碼,讓程序自然結束。 } }
對於簡單的應用系統,我們直接可以在System.exit(0)代碼執行前,添加需要在應用程序退出前需要完成的工作,如:關閉網絡連接,關閉數據庫連接等。
然而,對於比較復雜的多線程應用,線程運行的狀態較復雜,我們就很難預料程序何時結束,如何能在應用程序結束事件到來時,處理我們要做的工作呢?這就用到了Java對應用程序的退出的事件出處理機制。
對當前應用程序對象的獲得,Java通過Runtime靜態方法:Runtime.getRuntime()通過Runtime的 void addShutdownHook(Thread hook) 法向Java虛擬機注冊一個shutdown鈎子事件,這樣一旦程序結束事件到來時,就運行線程hook,我們在實際應用時候,只要將程序需要完成之前做的一些工作直接通過線程hook來完成。具體演示代碼如下
1 /***************************************************************************** 2 * 本程序僅演示,如何在Java應用程序中添加系統退出事件處理機制 3 *****************************************************************************/ 4 import java.util.*; 5 import java.io.*; 6 /** 7 * This application is used to demo how to hook the event of an application 8 */ 9 10 public class Untitled1 { 11 12 public Untitled1() { 13 doShutDownWork(); 14 } 15 16 /*************************************************************************** 17 * This is the right work that will do before the system shutdown 18 * 這里為了演示,為應用程序的退出增加了一個事件處理, 19 * 當應用程序退出時候,將程序退出的日期寫入 d:\t.log文件 20 **************************************************************************/ 21 22 private void doShutDownWork() { 23 Runtime.getRuntime().addShutdownHook(new Thread() { 24 public void run() { 25 try { 26 FileWriter fw = new FileWriter("d:\\t.log"); 27 System.out.println("Im going to end"); 28 fw.write("the application ended! " + (new Date()).toString()); 29 fw.close(); 30 } catch (IOException ex) { 31 } 32 } 33 }); 34 35 } 36 37 /**************************************************** 38 * 這是程序的入口,僅為演示,方法中的代碼無關緊要 39 ***************************************************/ 40 41 public static void main(String[] args) { 42 43 Untitled1 untitled11 = new Untitled1(); 44 long s = System.currentTimeMillis(); 45 for (int i = 0; i < 1000000000; i++) { 46 //在這里增添您需要處理代碼 47 } 48 long se = System.currentTimeMillis(); 49 System.out.println(se - s); 50 } 51 52 }
