简体   繁体   English

在ExecutorService中捕获所有期货/可赎回债券的异常

[英]Catching Exceptions of all Futures/Callables in an ExecutorService

I have an ExecutorService containing a number of running Callables . 我有一个ExecutorService其中包含许多正在运行的Callables I have a list of Futures for these Callables . 我有这些CallablesFutures清单。 I want to find out as soon as possible if one of the Callables throws an Exception . 我想尽快找出其中一个Callables抛出Exception All Callables are equally likely to throw an Exception . 所有Callables都有可能抛出Exception The Callables usually run for several hours. Callables通常运行几个小时。

The usual approach seems to be to use the Future.get() method. 通常的方法似乎是使用Future.get()方法。 However, you can only use this for one Future . 但是,您只能将此用于一个Future If another Future throws an Exception I am not notified. 如果另一个Future引发Exception不会通知我。 So I was thinking of writing a loop that checks the Future.isDone() method for all Futures and sleeping for some time after each iteration. 因此,我正在考虑编写一个循环,该循环检查所有Future的Future.isDone()方法,并在每次迭代后休眠一段时间。 However, this approach is not really nice, so I was wondering if there is a better way of doing this? 但是,这种方法并不是很好,所以我想知道是否有更好的方法?

You should use an ExecutorCompletionService , wrap your executor with it and then calling #take() will return the first completed result. 您应该使用ExecutorCompletionService ,用它包装您的执行ExecutorCompletionService ,然后调用#take()将返回第一个完成的结果。

Example: 例:

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();

You can use CompletableFuture for your use-case 您可以在用例中使用CompletableFuture

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

Returns a new CompletableFuture that is completed when any of the given CompletableFutures complete, with the same result. 返回一个新的CompletableFuture,它在任何给定的CompletableFutures完成时完成,并具有相同的结果。 Otherwise, if it completed exceptionally, the returned CompletableFuture also does so, with a CompletionException holding this exception as its cause. 否则,如果异常完成,则返回的CompletableFuture也会这样做,并且CompletionException将此异常作为其原因。 If no CompletableFutures are provided, returns an incomplete CompletableFuture. 如果未提供CompletableFuture,则返回不完整的CompletableFuture。

You should store all your futures in a list. 您应该将所有期货存储在列表中。 ` `

Now 现在

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
    }
}

You may obtain a CompletableFuture like 您可能会获得类似的CompletableFuture

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

If you don't want to use explicit executor pool 如果您不想使用显式执行程序池

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

However, in this case it will be submitted to the ForkJoinPool .commonPool() 但是,在这种情况下,它将被提交到ForkJoinPool .commonPool()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM