在JDK并发包中有这么一个类ExecutorCompletionService,提交任务后,能够按任务返回结果的先后顺序来获取各任务运行后的结果。
该类实现了接口CompletionService:
public interface CompletionService<V> {Future<V> submit(Callable<V> task);Future<V> submit(Runnable task, V result);Future<V> take() throws InterruptedException;Future<V> poll();Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;}
该接口定义了一系列方法:提交实现了Callable或Runnable接口的任务。并获取这些任务的结果。
ExecutorCompletionService实现了CompletionService。内部通过Executor以及BlockingQueue来实现接口提出的规范。当中,Executor由调用者传递进来。而Blocking能够使用默认的LinkedBlockingQueue,也能够由调用者传递。另外,该类还会将提交的任务封装成QueueingFuture,这样就能够实现FutureTask.done()方法,以便于在任务运行完成后,将结果放入堵塞队列中。
QueueingFuture为内部类:
private class QueueingFuture extends FutureTask<Void> {QueueingFuture(RunnableFuture<V> task) {super(task, null);this.task = task;}protected void done() { completionQueue.add(task); }private final Future<V> task;}
当中。done()方法就是在任务运行完成后,将任务放入队列中。
在提交任务时,将任务封装成QueueingFuture:
public Future<V> submit(Callable<V> task) {if (task == null) throw new NullPointerException();RunnableFuture<V> f = newTaskFor(task);executor.execute(new QueueingFuture(f));return f;}
在调用take()、poll()方法时,会从堵塞队列中获取Future对象,以取得任务运行的结果。