2017-03-06 4 views
1

Callablesの数値を含むExecutorServiceがあります。私はこれらのCallablesFuturesのリストを持っています。 CallablesのいずれかがExceptionを投げた場合、できるだけ早く見つけたいと思います。 CallablesはすべてExceptionを投げる可能性があります。 Callablesは通常数時間実行されます。ExecutorService内のすべての先物/呼び出し可能コードの例外のキャッチ

通常の方法は、Future.get()メソッドを使用することです。ただし、これは1つのFutureに対してのみ使用できます。別のFutureExceptionを投げた場合、私は通知されません。だから私はすべての先物のために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

あなたのユースケースのために

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

CompletableFutureを使用することができますが同じで、完全な 与え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 
    } 
} 

あなたはこのような場合、それには、しかし、明示的なエグゼキュータ・プール

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

を使用したくない場合は、CompletableFuture

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

を得ることができますForkJoinPool .commonPool()

に送信されます。
+0

あなたが持っているものがすべて 'Future'であるときに、' CompletableFuture'を得るための重要なステップについて、この答えはグロスです。 – Magnus

+0

同意して、同じ – Rahul

関連する問題