import java.util.concurrent.*; public class CallableDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { //建立一個線程池 ExecutorService pool = Executors.newSingleThreadExecutor(); //建立有返回值的任務 Callable callable = new MyCallable("zhangsan"); //執行任務並獲取Future對象 Future future = pool.submit(callable); //從Future對象上獲取任務的返回值,並輸出到控制檯 System.out.println("等待結果..."); System.out.println("獲得結果:"+future.get().toString()); //關閉線程池 pool.shutdown(); } } class MyCallable implements Callable{ private String name; MyCallable(String name) { this.name = name; } @Override public Object call() throws Exception { Thread.sleep(2000); return name + "返回的內容"; } }
CompletionService用於提交一組Callable任務,其take()方法返回已完成的一個Callable任務對應的Feture對象。 java
CompletionService採起的是BlockingQueue<Future<V>>無界隊列來管理Future。則有一個線程執行完畢把返回結果放到BlockingQueue<Future<V>>裏面。就能夠經過completionServcie.take().get()取出結果,同時還有一個poll()方法,這兩個方法的區別以下: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 void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(10); CompletionService<Integer> completionServcie = new ExecutorCompletionService<Integer>(pool); try { for (int i = 0; i < 10; i++) { completionServcie.submit(new MyCallable(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(); } } } class MyCallable implements Callable<Integer>{ private int i; Task(int i) { this.i = i; } @Override public Object call() throws Exception { Thread.sleep(new Random().nextInt(5000)); System.out.println(Thread.currentThread().getName() + " " + i); return i; } }