簡體   English   中英

並發和例外

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM