2016-05-16 22 views
0

我試圖關閉應用程序,每當有任何致命的 錯誤/異常來臨,但在關閉應用程序之前,我當前的 線程/任務應該完成,所以我在run()內寫入mainThread.join() ,無異常時工作正常。但是每當我的 doTask()拋出異常那個時候join()永遠等待。join()在發生異常時永久等待,jvm關機掛鉤不工作

public class POC 
{ 
    public void doTask() throws Exception 
    { 
     throw new Exception("Fatal Error"); 
     //throw new Exception("Fatal Error"); By commenting working fine. 
    } 

    public static void main(String[] args) 
    { 
     POC ob = new POC(); 
     final Thread mainThread = Thread.currentThread(); 
     Runtime.getRuntime().addShutdownHook(new Thread() 
     { 
      public void run() 
      { 
       try 
       { 
        System.out.println("Join() Start"); 
        mainThread.join(); 
        System.out.println("Join() End"); //Why this is not printing? 
       } 
       catch (InterruptedException e) 
       { 
        e.printStackTrace(); 
       }    
      } 
     }); 

     try 
     { 
      System.out.println("Before doTask()");   
      ob.doTask(); //User Defined Run() 
      System.out.println("After doTask()"); 
     } 
     catch (Exception ex)     // FATAL 
     { 
      System.err.println("Exception : " + ex.getLocalizedMessage()); 
      System.exit(-1); 
     } 
    } 
} 

OutPut : 0 
Before Run() 
Exception : Fatal Error 
Join() Start 

爲什麼System.out.println("Join() End");不打印?

+0

>請讓我知道,有沒有解決方案來釋放僵局並強行關閉jvm。 –

回答

1

你有一個簡單的死鎖。 當你拋出一個異常,異常處理程序調用System.exit(-1),這是堵,看到的Javadoc:

通過啓動關閉序列

終止當前運行的Java虛擬機...

虛擬機器的關機順序由兩個階段組成。在第一階段,所有已註冊的#addShutdownHook關機掛鉤(如果有的話)都以某些未指定的順序啓動,並允許同時運行,直至完成

所以主線程中System#exit呼叫等待,直到所有關閉鉤子將完成你唯一的關閉掛鉤塊並等待主線程將完成(在System#exit等待... GOTO 1)。

+0

>請讓我知道,是否有任何解決方案來釋放僵局並強行關閉jvm。 –

+1

@IndrajeetKumarSharma不會加入關閉鉤子中的主線程:它會導致死鎖並且沒有意義 – qwwdfsad