等待未来的名单 [英] Waiting on a list of Future

查看:160
本文介绍了等待未来的名单的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个返回 List 期货的方法

I have a method which returns a List of futures

List<Future<O>> futures = getFutures();

现在我要等到所有期货都成功处理完成或任何输出为的任务由未来返回抛出异常。即使一个任务抛出异常,也没有必要等待其他期货。

Now I want to wait until either all futures are done processing successfully or any of the tasks whose output is returned by a future throws an exception. Even if one task throws an exception, there is no point in waiting for the other futures.

简单的方法是

wait() {

   For(Future f : futures) {
     try {
       f.get();
     } catch(Exception e) {
       //TODO catch specific exception
       // this future threw exception , means somone could not do its task
       return;
     }
   }
}

但这里的问题是例如,第四个未来抛出异常,然后我将不必要地等待前3个期货可用。

But the problem here is if, for example, the 4th future throws an exception, then I will wait unnecessarily for the first 3 futures to be available.

如何解决这个问题?会以任何方式倒计时闩锁帮助吗?我无法使用Future isDone ,因为java doc说

How to solve this? Will count down latch help in any way? I'm unable to use Future isDone because the java doc says

boolean isDone()
Returns true if this task completed. Completion may be due to normal termination, an exception, or cancellation -- in all of these cases, this method will return true.


推荐答案

您可以使用CompletionService ,一旦准备就会收到期货,如果其中一个抛出异常取消处理。这样的事情:

You can use a CompletionService to receive the futures as soon as they are ready and if one of them throws an exception cancel the processing. Something like this:

Executor executor = Executors.newFixedThreadPool(4);
CompletionService<SomeResult> completionService = 
       new ExecutorCompletionService<SomeResult>(executor);

//4 tasks
for(int i = 0; i < 4; i++) {
   completionService.submit(new Callable<SomeResult>() {
       public SomeResult call() {
           ...
           return result;
       }
   });
}

int received = 0;
boolean erros = false;

while(received < 4 && !errors) {
      Future<SomeResult> resultFuture = completionService.take(); //blocks if none available
      try {
         SomeResult result = resultFuture.get();
         received ++;
         ... // do something with the result
      }
      catch(Exception e) {
             //log
         errors = true;
      }
}

我认为您可以进一步改进以取消任何仍在执行任务,如果其中一个抛出错误。

I think you can further improve to cancel any still executing tasks if one of them throws an error.

编辑:我在这里找到了一个更全面的例子: http://blog.teamlazerbeez.com/2009/04/29/java-completionservice/

I've found a more comprehensive example here: http://blog.teamlazerbeez.com/2009/04/29/java-completionservice/

这篇关于等待未来的名单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆