public interface CompletionService<V>
將生產新的異步任務與使用已完成任務的結果分離開來的服務。生產者 submit 執行的任務。使用者 take 已完成的任務,並按照完成這些任務的順序處理它們的結果。例如,CompletionService 可以用來管理異步 IO ,執行讀操作的任務作爲程序或系統的一部分提交,然後,當完成讀操作時,會在程序的不同部分執行其他操作,執行操作的順序可能與所請求的順序不同。
通常,CompletionService 依賴於一個單獨的 Executor
來實際執行任務,在這種情況下,CompletionService 只管理一個內部完成隊列。ExecutorCompletionService
類提供了此方法的一個實現。
內存一致性效果:線程中向 CompletionService
提交任務之前的操作 happen-before 該任務執行的操作,後者依次 happen-before 緊跟在從對應 take()
成功返回的操作。
// 這個東西的使用上很類似於CallableFutureTest,不同的是,它會首先取完成任務的線程。 public class CompletionServiceTest { public static void main(String[] args) throws InterruptedException, ExecutionException { ExecutorService exec = Executors.newFixedThreadPool(10); // 創建CompletionService CompletionService<String> serv = new ExecutorCompletionService<String>(exec); for (int index = 0; index < 5; index++) { final int NO = index; // Callable 接口類似於 Runnable Callable<String> downImg = new Callable<String>() { public String call() throws Exception { Thread.sleep((long) (Math.random() * 10000)); return "Downloaded Image " + NO; } }; // 提交要執行的值返回任務,並返回表示掛起的任務結果的 Future。在完成時,可能會提取或輪詢此任務。 serv.submit(downImg); } Thread.sleep(1000 * 2); System.out.println("Show web content"); for (int index = 0; index < 5; index++) { // 獲取並移除表示下一個已完成任務的 Future,如果目前不存在這樣的任務,則等待。 Future<String> task = serv.take(); // 如有必要,等待計算完成,然後獲取其結果。 String img = task.get(); System.out.println(img); } System.out.println("End"); // 關閉線程池 exec.shutdown(); } }