CompletionService
将执行服务与类似 Queue
的接口组合,从任务执行中删除任务结果的处理。CompletionService
接口包含用来提交将要执行的任务的 submit()
方法和用来询问下一完成任务的 take()
/poll()
方法。
CompletionService
允许应用程序结构化,使用 Producer/Consumer 模式,其中生产者创建任务并提交,消费者请求完成任务的结果并处理这些结果。CompletionService
接口由 ExecutorCompletionService
类实现,该类使用 Executor
处理任务并从CompletionService
导出 submit/poll/take 方法。
下列代码使用 Executor
和 CompletionService
来启动许多“solver”任务,并使用第一个生成非空结果的任务的结果,然后取消其余任务:
void solve(Executor e, Collection<Callable<Result>> solvers)
throws InterruptedException {
CompletionService<Result> ecs =
new ExecutorCompletionService<Result>(e);
int n = solvers.size();
List<Future<Result>> futures =
new ArrayList<Future<Result>>(n);
Result result = null;
try {
for (Callable<Result> s : solvers)
futures.add(ecs.submit(s));
for (int i = 0; i < n; ++i) {
try {
Result r = ecs.take().get();
if (r != null) {
result = r;
break;
}
} catch(ExecutionException ignore) {}
}
}
finally {
for (Future<Result> f : futures)
f.cancel(true);
}
if (result != null)
use(result);
}