當向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