package com.dy.pool; import java.util.concurrent.*; /** * 1: Callable<V> 返回結果而且可能拋出異常的任務。實現者定義了一個不帶任何參數的叫作 call 的方法。 Callable 接口相似於 Runnable,二者都是爲那些其實例可能被另外一個線程執行的類設計的。 可是 Runnable 不會返回結果,而且沒法拋出通過檢查的異常。 2: Future<V> 表示異步計算的結果 Future 表示異步計算的結果。它提供了檢查計算是否完成的方法,以等待計算的完成,並獲取計算的結果。 3: CompletionService<V> 將生產新的異步任務與使用已完成任務的結果分離開來的服務 , * 生產者 submit 執行的任務。使用者 take 已完成的任務,並按照完成這些任務的順序處理它們的結果。 * * * 4:FutureTask<V> 可取消的異步計算。實現了RunbaleFuture, * * RunbaleFuture 繼承了Future和Runbale,因此FutureTask<V>能夠當作一個線程去提交或執行。 * * 返回FutureTask的操做也能夠用Future來接受 * * 利用開始和取消計算的方法、查詢計算是否完成的方法和獲取計算結果的方法,此類提供了對 Future 的基本實現。 * * 僅在計算完成時才能獲取結果;若是計算還沒有完成,則阻塞 get 方法。一旦計算完成,就不能再從新開始或取消計算。 可以使用 FutureTask 包裝 Callable 或 Runnable 對象。由於 FutureTask 實現了 Runnable, 因此可將 FutureTask 提交給 Executor 執行。 * * @author dengyang * * @2012-4-13下午12:57:57 */ public class CallableAndFuture { /** * @param args */ public static void main(String[] args) { /** * Future使用 */ ExecutorService threadPool = Executors.newSingleThreadExecutor(); Future<String> future = threadPool.submit(new Callable<String>(){ public String call() throws Exception { Thread.sleep(1000); return "I am dengyang"; } }); System.out.println("我先去作其餘事情了..."); try { System.out.println("The Callable return :"+future.get()); // System.out.println("The Callable return :"+future.get(100,TimeUnit.SECONDS)); } catch (Exception e) { e.printStackTrace(); } threadPool.shutdown(); /** * FutureTask使用 */ ExecutorService executor = Executors.newFixedThreadPool(3); FutureTask<String> futureTask = new FutureTask<String>(new Callable<String>() { public String call() { return "我執行完了"; }}); // executor.submit(futureTask); executor.execute(futureTask); System.out.println("線程在執行FutureTask,我先去處理別的事情了"); try { System.out.println("futureTask return:"+futureTask.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } executor.shutdown(); /* CompletionService使用 * 有多個線程,哪一個先返回數據,就先獲取哪一個 */ ExecutorService threadPool2 = Executors.newFixedThreadPool(10); CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPool2); for(int i=0;i<10;i++){ final int seq = i; completionService.submit(new Callable<Integer>(){ public Integer call() throws Exception { return seq; } }); } System.out.println("多線程執行任務時,我先去作其餘事情了..."); try { System.out.println("the first result of The Callable return :"+completionService.take().get()); for(int i=0;i<10;i++){ System.out.println(" The Callable return :"+completionService.take().get()); } } catch (Exception e) { e.printStackTrace(); } threadPool2.shutdown(); } }
使用Callable,Future返回結果
Future<V>表明一個異步執行的操做,經過get()方法能夠得到操做的結果,若是異步操做尚未完成,則,get()會使當 前線程阻塞。FutureTask<V>實現了Future<V>和Runable<V>。Callable表明一 個有返回值得操做。 java
ExecutoreService提供了submit()方法,傳遞一個Callable,或Runnable,返回Future。若是Executor後臺線程池尚未完成Callable的計算,這調用返回Future對象的get()方法,會阻塞直到計算完成。 數組
FutureTask使用過程當中,咱們一般能夠迭代FutureTask的數組,若是任務尚未完成則當前線程會阻塞, 多線程
若是咱們希 望任意字任務完成後就把其結果加到result中,而不用依次等待每一個任務完成,可使CompletionService。 異步
生產者submit()執行 的任務。使用者take()已完成的任務,並按照完成這些任務的順序處理它們的結果 。 spa
也就是調用CompletionService的take方法是,會返回按完成順序放回任務的結果, 線程
CompletionService內部維護了一個 阻塞隊列BlockingQueue,若是沒有任務完成,take()方法也會阻塞。 設計
類模型: code