2009-10-20 127 views
2

我製作了一個多線程程序。其中,主線程啓動10個線程,但問題是每當其中一個線程出現異常時,整個應用程序就會停止。線程異常

  1. 但我想,只要一個異常發生在一個線程中,只有線程應該被停止,其他線程繼續工作。我怎樣才能做到這一點?

  2. 其次,我希望主線程應該在所有10個線程完成後纔會停止。我怎樣才能做到這一點?

回答

4

你可以使用一個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. 
    } 
} 
1

環繞與try/catch語句的所有

public void run() { 
    try { 
     .... 
    } catch(Exception e){} 
} 

雖然我會更好地嘗試爲那些異常的原因。

0

關於你的第一點,我會建議你在拋出異常時優雅地退出一個線程,也就是說,在線程內捕獲它(並且不要讓它冒泡到jvm)。

1

對於#1,如果這是您的預期目標,則應考慮您如何處理該異常以及您期望的異常類型。如果這些是應用程序故障,則可以確定一種更有用的方法來捕獲單個線程級別的異常,並將重要信息反饋給父線程。另外一個爲你管理線程池的解決方案可能是@Adamski指出的一個更好的方法,就像ExecutorServce ThreadPoolExecutor的實現一樣,但是你需要了解異常,以及是否可以用一些額外的邏輯來阻止它們如果沒有,那麼有效管理工作的更好方式就是要走的路。

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/ThreadPoolExecutor.html

#2,加入(),或使用一個線程池來管理它們。