当向Executor提交批处理任务时,而且但愿在它们完成后得到结果,若是用FutureTask,你能够循环获取task,并用future.get()去获取结果,可是若是这个task没有完成,你就得阻塞在这里,这个实效性不高,其实在不少场合,其实你拿第一个任务结果时,此时结果并无生成并阻塞,其实在阻塞在第一个任务时,第二个task的任务已经早就完成了,显然这种状况用future task不合适的,效率也不高。
本身维护list和CompletionService的区别: java
方法区别: app
如下是jdk关于CompletionService的简介: dom
废话少说,直接看代码: 异步
package com.lucky.concurrent; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class CompletionServiceDemo { public static class Task implements Callable<Integer> { private int i; Task(int i) { this.i = i; } @Override public Integer call() throws Exception { Thread.sleep(new Random().nextInt(5000)); System.out.println(Thread.currentThread().getName() + " " + i); return i; } } public void run() { ExecutorService pool = Executors.newFixedThreadPool(10); CompletionService<Integer> completionServcie = new ExecutorCompletionService<Integer>( pool); try { for (int i = 0; i < 10; i++) { completionServcie.submit(new CompletionServiceDemo.Task(i)); } for (int i = 0; i < 10; i++) { // take 方法等待下一个结果并返回 Future 对象。 // poll 不等待,有结果就返回一个 Future 对象,不然返回 null。 System.out.println(completionServcie.take().get()); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } finally { pool.shutdown(); } } public static void main(String[] args) { new CompletionServiceDemo().run(); } }直接结果:
从结果中不难看出。只要有一个线程执行完毕后,主程序就立马获取结果。 ide