使用者關閉關閉程式,需要做一些善後的清理工作,但問題是,某些使用者不會按照推薦的方法關閉應用程式,肯能導致善後工作無法進行。像tomcat調用server的start方法啟動容器,然後會逐級調用start。當發出關閉命令是會啟動關閉功能,但是關閉可能會有一些意外產生,導致應用程式沒有進入到我們制定的關閉方法去。如何解決這個問題呢,使得即使有意外也能正常進入關閉流程。
好在java提供了一種優雅的方式去解決這種問題。使得關閉的善後處理的代碼能執行。java的關閉鉤子能確保總是執行,無論使用者如何終止應用程式。除非使用者kill,這個是個死穴。
對java而言,虛擬機器會對以下幾種操作進行關閉:
(1)系統調用System.exit()方法
(2)程式最後一個守護線程退出時,應用程式正常退出。
(3)使用者強行中斷程式運行,比如ctrl+c等其他方式中斷java程式
關閉鉤子的產生:
1.建立Thread的子類
2.實現run方法,應用程式關閉時會調用該方法,不需要調用start方法
3.在應用中執行個體化關閉鉤子類
4.使用Runtime註冊關閉鉤子
public class ExitHook{public static void main(String[] args)throws IOException{final FileOutputStream fos;fos = new FileOutputStream("a.bin");System.out.println("程式開啟實體資源。");//為系統註冊關閉鉤子Runtime.getRuntime().addShutdownHook(new Thread() {public void run(){//使用關閉鉤子來關閉資源if (fos != null){try{fos.close();}catch (Exception ex){ex.printStackTrace();}}System.out.println("程式關閉了實體資源。");}});System.exit(0);}}
關閉鉤子,負責在程式退出時回收系統資源,運行上面程式,將看到
系統可以正常關閉實體資源。
建議:同一個JVM最好只使用一個關閉鉤子,而不是每個服務都使用一個不同的關閉鉤子,使用多個關閉鉤子可能會出現當前這個鉤子所要依賴的服務可能已經被另外一個關閉鉤子關閉了。為了避免這種情況,建議關閉操作在單個線程中串列執行,從而避免了再關閉操作之間出現競態條件或者死結等問題。
http://blog.csdn.net/huangmin2050/article/details/7694610
http://blog.sina.com.cn/s/blog_6145ed8101015tbu.html
http://www.cnblogs.com/langtianya/p/4300282.html