一、ExecutorCompletionService:提交任務線程,每個線程任務直線完成後,將返回值放在阻塞隊列中,而後能夠經過阻塞隊列的take()方法返回 對應線程的執行結果,是Executor和BlockingQueue的結合體,xecutorCompletionService在構造函數中會建立一個BlockingQueue(使用的基於鏈表的無界隊列LinkedBlockingQueue),該BlockingQueue的做用是保存Executor執行的結果。當計算完成時,調用FutureTask的done方法。當提交一個任務到ExecutorCompletionService時,首先將任務包裝成QueueingFuture,它是FutureTask的一個子類,而後改寫FutureTask的done方法,以後把Executor執行的計算結果放入BlockingQueue中html
submit的task不必定是按照加入本身維護的list順序完成的。函數
從list中遍歷的每一個Future對象並不必定處於完成狀態,這時調用get()方法就會被阻塞住,若是系統是設計成每一個線程完成後就能根據其結果繼續作後面的事,這樣對於處於list後面的可是先完成的線程就會增長了額外的等待時間。spa
而CompletionService的實現是維護一個保存Future對象的BlockingQueue。只有當這個Future對象狀態是結束的時候,纔會加入到這個Queue中,take()方法其實就是Producer-Consumer中的Consumer。它會從Queue中取出Future對象,若是Queue是空的,就會阻塞在那裏,直到有完成的Future對象加入到Queue中。線程
二、futureTask:任務狀態由變量state表示,任務狀態都基於state判斷。而futureTask的阻塞則是經過自旋(for循環)+掛起線程(spark)實現.揭祕futureTask設計