2013-04-11 23 views
1

不知道是否可以存在的情況下乘法異常可以從不同線程同時拋出
如果是這樣,如何正確處理它們以便恢復應用程序並繼續執行?併發與異常

感謝您的回答。
歡迎舉例說明。

+0

分別處理每個線程的run()方法中的每個異常 – BlackJoker 2013-04-11 05:19:40

+0

@ Spring.Rush - 很好的例子仍然受歡迎) – 2013-04-11 05:20:44

+0

多線程可以同時執行很多事情,如拋出和處理多個異常。你能舉一個例子說明它們發生的順序是什麼嗎? – 2013-04-11 07:27:33

回答

3

我不知道是否可以存在的情況時,可以從不同的線程同時拋出乘法異常。

是的,這是可能的。

如果是這樣,如何正確處理它們以恢復應用程序並繼續它的執行?

catch塊在發生異常的線程中發生,因此每個線程都可以執行自己的清理。

如果catch塊需要處理從多個線程引用的對象,則需要小心地正確鎖定,就好像該對象可由多個未處理異常的線程訪問一樣。

如果您已經安裝了自定義UncaughtExceptionHandler,那麼只要處理可變狀態,您就需要在該處理程序中進行同步,以便在從多個線程同時調用時不會遇到併發性問題。


如果catch塊是在方法從線程開始了嗎?

Thread th = new Thread(new Runnable() { 
    public void run() { 
    throw new NullPointerException(); 
    } 
}); 
th.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { 
    public void uncaughtException(Thread thread, Throwable throwable) { 
    // This gets run because the NPE ends the child thread. 
    System.err.println("Uncaught " + throwable); 
    } 
}); 
try { 
    th.start(); 
} catch (NullPointerException ex) { 
    System.err.println("Not reached"); 
} 

在父堆棧幀捕獲塊時子線程拋出異常沒有達到。

發生這種情況是因爲啓動線程不像分叉進程。當分叉一個進程時,子進程獲得父進程堆棧的副本,​​但是當啓動一個線程時,子進程將從它自己的空棧開始。

+1

如果catch塊在啓動線程的方法中,該怎麼辦? – 2013-04-11 05:23:44

+0

@spin_eight,子線程不會繼承父線程堆棧,所以子進程拋出的異常不會到達父進程中的catch子塊。 – 2013-04-11 05:24:36

+0

非常感謝,我應該深入瞭解異常機制。 – 2013-04-11 05:31:49

1

如果多個線程爲了工作而依靠一個資源並且一個資源有錯誤,那麼使用該資源的線程將全部拋出異常。你想如何處理這個問題取決於你,但我建議每個線程都討論它自己的異常,除非你有另一個線程來管理這些線程和handels例外。

例如,在我去年夏天製作的遊戲中,我的音響系統有許多頻道,每個頻道都有自己的線程,還有一個線程負責管理加載並將聲音數據添加到頻道。我最初爲每個線程使用Clip對象,如果太多的剪輯嘗試播放相同的聲音,有時會導致錯誤。我爲每個頻道添加了一個標誌,以表明是否在頻道中放映了某個音頻。如果我的聲音管理器在嘗試添加聲音時發現有錯誤的頻道,它會移除該頻道,在其位置添加一個新頻道,並將該頻道的字符串提供給該頻道以反映裝入內存中的聲音字節。 許多線程同時使用Clip接口還存在其他問題。很少發生,整個虛擬機將因「不支持小轉儲」而失敗。由於catch子句不能阻止虛擬機的錯誤,因此我切換到另一種播放音效的方法:SourceDataLine。我沒有問題。

運行多個線程還有很多可能的錯誤。處理這些錯誤的方法有很多。

+0

謝謝你的有趣的例子,也爲國旗的解決方案。現在我看到多重同時異常的情況並不像我最初考慮的那樣罕見。據我記得應該使用這種標誌的揮發性變質劑? – 2013-04-11 05:45:14

+0

我不確定volatile修飾符的作用。我使用同步方法來獲取和設置數據。以下是我的聲音管理器用來檢查錯誤的方法:boolean ok = true; public synchronized void setStatus(boolean status){this.ok = status;} public synchronized boolean getStatus(){return this.ok;} synchronized修飾符的作用是爲對象或函數添加一個鎖。一個線程必須獲得這個鎖來使用一個對象,等待另一個線程是否擁有它想要的對象的鎖,然後在線程完成使用時釋放該對象上的鎖。 – dmichaelc 2013-04-11 06:11:20