[英]Concurrency & exceptions
我想知道當多個異常可以同時從不同的線程拋出時是否存在。
如果是這樣, 如何正確處理它們以恢復應用程序並繼續執行?
謝謝你的回答。
很好的例子受到歡迎。
我想知道當多個異常可以同時從不同的線程拋出時是否存在。
對的,這是可能的。
如果是這樣,如何正確處理它們以恢復應用程序並繼續執行?
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");
}
當子線程拋出異常時,未到達父堆棧幀中的catch塊。
發生這種情況是因為啟動線程不像分支進程。 在分叉進程時,子進程獲取父進程堆棧的副本,但是在啟動線程時,子進程以其自己的空堆棧開始。
如果多個線程依賴於一個資源才能工作並且一個資源有錯誤,那么使用該資源的線程都會拋出異常。 您希望如何處理這個問題取決於您,但我建議每個線程都有自己的異常,除非您有另一個線程來管理這些線程並為它們處理異常。
例如,在我去年夏天制作的游戲中,我的聲音系統有許多通道,每個通道都有自己的線程,還有一個線程管理加載並將聲音數據添加到通道。 我最初為每個線程使用了Clip對象,如果太多的剪輯試圖播放相同的聲音,有時會導致錯誤。 我為每個頻道添加了一個標志,以告知是否在頻道中拋出了一個異常。 如果我的聲音管理器在嘗試添加聲音時發現了一個有錯誤的通道,它將刪除該通道,在其位置添加一個新通道,並將該字符串提供給通道以引用內存中加載的聲音字節。 許多線程同時使用Clip接口還存在其他問題。 由於“不支持小型轉儲”,整個虛擬機很少會出現故障。 由於catch子句無法阻止虛擬機錯誤,我切換到另一種聲音效果播放方法:SourceDataLine。 我沒有遇到任何問題。
運行多個線程有很多可能的錯誤。 處理這些錯誤的方法也很多。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.