我正在使用 Callable 和 ExecutorService 在我的應用程式中使用多執行緒。
萬一如果從一個執行緒拋出任何例外需要停止所有執行緒,即使它的作業已經完成并且需要將該例外拋出給呼叫類方法。為此,我使用了一個shutDownNow() 方法。
這是正確的方法嗎?或者還有其他有效的方法嗎?
ExecutorService exSvc = Executors.newFixedThreadPool(5);
exSvc.setKeepAliveTime(60, TimeUnit.SECONDS);
List<Future<Integer>> futureList = new LinkedList();
for(int i=0; i<50;i ){
futureList.add(exSvc.submit(
new Callable<Integer>() {
public Integer call() throws Exception{
int num = new Random().nextInt(1000);
if(num==500){
throw new Exception("Error");
}
return num;
}
}));
}
for(int i=0; i<50; i ){
try {
int value = futureList.get(i).get();
} catch (Exception e) {
exSvc.shutdownNow();
throw new Exception("Error");
}
}
uj5u.com熱心網友回復:
這應該適用于您的示例。但是,請務必正確處理可呼叫物件中的執行緒中斷。
請注意,其他任務將在盡力而為的基礎上被取消,并且只有在您注意到其中一個任務引發了例外之后。例如,如果任務沒有。5 已經拋出例外,你必須等待任務 0-4 完成,然后你才注意到任務 5 失敗了。
或者,您可以像這里一樣對 ThreadPoolExecutor 進行子類化,以盡早檢測到例外。
uj5u.com熱心網友回復:
正如 ciamei 所說,如果您想盡早檢測到例外,也許您可??以使用CountDownLatch:
CountDownLatch cdl = new CountDownLatch(1);
AtomicInteger successCount = new AtomicInteger();
AtomicBoolean fail = new AtomicBoolean();
int taskSize = 50;
for(int i=0; i<taskSize;i ){
futureList.add(exSvc.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int num = new Random().nextInt(1000);
if(num == 500){
fail.set(true);
cdl.countDown();
throw new Exception("Error");
}
if (successCount.incrementAndGet() == taskSize) {
cdl.countDown();
}
return num;
}
}));
}
try {
cdl.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
if (fail.get()) {
exSvc.shutdownNow();
throw new Exception("Error");
}
//...
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/406210.html
標籤:
