2017-03-06 34 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