等待未来的名单 [英] Waiting on a list of Future
问题描述
我有一个方法可以返回期货的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;
}
}
}
但这里的问题是,例如,如果第 4 个期货抛出异常,那么我将不必要地等待前 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 文档说
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 errors = 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.
这篇关于等待未来的名单的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!