CompletionService接口是将生产新的异步任务与使用已完成任务的结果分离开来的服务。生产者利用submit()提交要执行的任务。使用者利用take()获取并移除已完成的任务的返回值,并按照完成这些任务的顺序处理它们的结果。
通常,CompletionService 依赖于一个单独的 Executor 来实际执行任务,在这种情况下,CompletionService 只管理一个内部完成队列。ExecutorCompletionService 类提供了此方法的一个实现。此类将那些完成时提交的任务放置在可使用take()访问的队列上。
方法摘要
Future<V> poll()
//获取并移除表示下一个已完成任务的 Future,如果不存在这样的任务,则返回 null。
Future<V> poll(long timeout, TimeUnit unit)
//获取并移除表示下一个已完成任务的 Future,如果目前不存在这样的任务,则将等待指定的时间(如果有必要)。
Future<V> submit(Callable<V> task)
//提交要执行的值返回任务,并返回表示挂起的任务结果的 Future。
Future<V> submit(Runnable task, V result)
//提交要执行的 Runnable 任务,并返回一个表示任务完成的 Future,可以提取或轮询此任务。
Future<V> take()
//获取并移除表示下一个已完成任务的 Future,如果目前不存在这样的任务,则等待。
示例
假定有针对某个问题的一组求解程序,每个求解程序都能返回某种类型的Result值,并且想同时运行它们,使用方法 use(Result r) 处理返回非 null 值的每个求解程序的返回结果。可以这样编写程序:
void solve(Executor e, Collection<Callable<Result>> solvers) throws InterruptedException, ExecutionException {
CompletionService<Result> ecs = new ExecutorCompletionService<Result>(e);
for (Callable<Result> s : solvers)
ecs.submit(s);
int n = solvers.size();
for (int i = 0; i < n; ++i) {
Result r = ecs.take().get();
if (r != null)
use(r);
}
}
本文就先讲到这里,想了解Java并发编程更多内容请参考:
- Java并发编程札记-目录