2011-07-12 92 views
21

假設線程是從主方法啓動的。如果在線程中拋出異常但在線程內未處理異常會發生什麼?java線程異常

是否有可能將異常傳播回主方法?

回答

32

我們正在討論從Thread.run方法拋出的未經檢查的異常。 默認情況下,你會得到某事像這樣在系統錯誤:

Exception in thread "Thread-0" java.lang.RuntimeException 
    at Main$1.run(Main.java:11) 
    at java.lang.Thread.run(Thread.java:619) 

這是的printStackTrace的未處理異常的結果。爲了處理它,你可以添加自己的UncaughtExceptionHandler:

Thread t = new Thread(new Runnable(){ 
     public void run() { 
      throw new RuntimeException(); 
     }  
    }); 
    t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 

     public void uncaughtException(Thread t, Throwable e) { 
      System.out.println("exception " + e + " from thread " + t); 
     } 
    }); 
    t.start(); 

要對所有線程使用一個靜態方法Thread.setDefaultUncaughtExceptionHandler設置處理程序。

0

如果異常不被try {} catch (Exception e){}處理,那麼它會被引發並拋出到被調用的函數。

如果是單獨的獨立線程,你不能將它傳播給對象,它是不是線程

或者其他一些信息,這裏的家長:How to throw a checked exception from a java thread?

0

通常情況下,如果你不自己實現異常,當發生一些異常時,它會關閉執行。

+0

只有它發生的線程 –

3

不,它不能。當你想到它時,main()方法可能在幾天前​​完成。

任何來自線程的未捕獲異常都會傳播到線程的UncaughtExceptionHandler。如果沒有定義的話,它會轉到線程組的處理程序,如果沒有設置,它會轉到默認處理程序。

+0

關於'days ago'的答案中的第一行有助於更好地理解問題。實際上,多個線程可以像發生(容易)共享數據的單獨進程那樣工作。可以使用單獨的進程和共享內存構建完全相同的模型(有些難度較大)。 – kevinarpe

0

該例外被UncaughtExceptionHandler捕獲。如果你願意的話,你可以在那裏捕獲它並將它傳播回主線程​​。

5

如果異常被該線程中運行的代碼捕獲並處理,那麼將處理該異常,但會寫入catch塊邏輯。我會假設這個答案的其餘部分是關於未捕獲的異常。

未捕獲的異常將導致線程退出。當它泡到Thread.run()的頂部時,將由線程的UncaughtExceptionHandler處理。默認情況下,這隻會將堆棧跟蹤打印到控制檯。線程本身將在此處退出 - 它無法繼續,因爲它的run()方法已完成。所以如果你想在你的主線程中重新進行異常處理,你可以定義一個UncaughtExceptionHandler來做這件事(這是一個非常簡單的接口),然後在創建線程後在產生的線程上調用Thread.setUncaughtExceptionHandler,傳入你的定製異常處理程序


唯一對編寫處理潛在棘手的部分是確定在哪裏和你要去究竟如何「插入」的拋出到你的主線程。如果你的線程不做其他事情,這將不是很明顯,而且很大程度上取決於你如何設計你的應用程序以及它的併發支持是什麼樣的。 (如果另一方面你的主線程正在等待另一個線程運行,那麼它變得更容易了,但在這種情況下,也許你的主線程應該提交一個任務給線程ExecutorService並阻塞一個Future,它會處理所有這些佈線/生命週期的東西嗎?)

相關問題