我製作了一個多線程程序。其中,主線程啓動10個線程,但問題是每當其中一個線程出現異常時,整個應用程序就會停止。線程異常
但我想,只要一個異常發生在一個線程中,只有線程應該被停止,其他線程繼續工作。我怎樣才能做到這一點?
其次,我希望主線程應該在所有10個線程完成後纔會停止。我怎樣才能做到這一點?
我製作了一個多線程程序。其中,主線程啓動10個線程,但問題是每當其中一個線程出現異常時,整個應用程序就會停止。線程異常
但我想,只要一個異常發生在一個線程中,只有線程應該被停止,其他線程繼續工作。我怎樣才能做到這一點?
其次,我希望主線程應該在所有10個線程完成後纔會停止。我怎樣才能做到這一點?
你可以使用一個ExecutorService(包含多個線程)調用提交處理工作的各個項目()。提交方法返回一個Future,它將封裝處理結果或拋出的任何異常。換句話說,如果發生異常,ExecutorService
內的線程將不會終止。
例
首先創建一個包含多個線程的執行服務:
ExecutorService execService = Executors.newFixedThreadPool(5);
定義的工作,我們希望提交的Callable
項目:
public class MyWorkItem implements Callable<Integer> {
public Integer call() throws Exception {
int result = new Random().nextInt(5);
// Randomly fail.
if (result == 0) {
throw new IllegalArgumentException("Fail!");
}
return result;
}
}
提交爲執行者服務做一些工作,並將Future<Integer>
存儲爲每個Callable<Integer>
。
List<Future<Integer>> futures = new LinkedList<Future<Integer>>();
for (int i=0; i<10; ++i) {
futures.add(execService.submit(new MyWorkItem()));
}
現在遍歷試圖檢索每個工作項目的結果(我們可以使用這個CompletionService
)期貨。
for (Future<Integer> future : futures) {
try {
Integer result = future.get();
} catch(Exception ex) {
// Handle exception.
}
}
在主方法結束時,您應該在每個啓動的線程上調用join
。
順便說一句:如果你想處理您的線程的例外,可以使用Thread.setDefaultUncaughtExceptionHandler()
環繞與try/catch語句的所有
public void run() {
try {
....
} catch(Exception e){}
}
雖然我會更好地嘗試爲那些異常的原因。
關於你的第一點,我會建議你在拋出異常時優雅地退出一個線程,也就是說,在線程內捕獲它(並且不要讓它冒泡到jvm)。
對於#1,如果這是您的預期目標,則應考慮您如何處理該異常以及您期望的異常類型。如果這些是應用程序故障,則可以確定一種更有用的方法來捕獲單個線程級別的異常,並將重要信息反饋給父線程。另外一個爲你管理線程池的解決方案可能是@Adamski指出的一個更好的方法,就像ExecutorServce ThreadPoolExecutor的實現一樣,但是你需要了解異常,以及是否可以用一些額外的邏輯來阻止它們如果沒有,那麼有效管理工作的更好方式就是要走的路。
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html
#2,加入(),或使用一個線程池來管理它們。