2017-03-06 82 views
1

我有一個ExecutorService,其中包含一些正在運行的Callables。我對這些Callables列出了Futures。我想盡快找出Callables之一是否會拋出Exception。所有Callables同樣可能會拋出ExceptionCallables通常運行幾個小時。捕捉ExecutorService中所有期貨/可加倉的例外情況

通常的做法似乎是使用Future.get()方法。但是,您只能將其用於Future。如果另一個Future引發Exception我沒有收到通知。所以我想寫一個循環,檢查所有期貨的Future.isDone()方法,並在每次迭代後睡眠一段時間。但是,這種方法並不好,所以我想知道是否有更好的方法來做到這一點?

+0

爲什麼不包裹你的可調用函數並在包裝器中處理每個錯誤? –

回答

2

您應該使用ExecutorCompletionService,將您的執行器包裝起來,然後調用#take()將返回第一個完成的結果。

例子:

CompletionService<Object> completionService = new ExecutorCompletionService<>(executor); 
//submit a bunch of tasks 
IntStream.range(0, 100).forEach(i-> completionService.submit(Object::new)); 
//Wait for any of them to complete, wrap in a loop to take them all 
completionService.take(); 
2

您可以使用CompletableFuture爲您的使用情況

static CompletableFuture<Object> anyOf(CompletableFuture<?>... cfs) 

返回完成時任 給出CompletableFutures的完整的新CompletableFuture,與同結果。否則,如果 它異常完成,則返回的CompletableFuture也會執行 ,因此,帶有此異常的CompletionException將作爲其原因。 如果沒有提供CompletableFutures,則返回一個不完整的 CompletableFuture。

您應該將所有期貨存儲在列表中。 `

現在

List<CompletableFuture<?>> futureList = // all futures; 
while(futureList.size()>0){ 
    CompletableFuture<?> completed = CompletableFuture.anyOf(futureList); //convert futureList to array 
    if(completed.isCompletedExceptionally()){ 
     // first future that completed with an exception 
    }else{ 
     //future completed without exception, store the result or process 
     futureList.remove(completed); // remove it from the incomplete list 
    } 
} 

您可能獲得CompletableFuture

final CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { 
     //...long running... 
     return "returnVal"; 
     }, 
    executor); //here executor is your executor pool 

如果你不想使用明確的執行池

final CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> { 
      //...long running... 
      return "returnVal"; 
      }); 

然而,在這種情況下,將提交至ForkJoinPool.commonmonitor()

+0

這個答案在獲得'CompletableFuture'的關鍵步驟中只有當你擁有一個'Future'時纔是有意義的。 – Magnus

+0

同意,更新了相同的答案 – Rahul