Java CompletionService 的作用與場景解析

b10l07發表於2018-04-20
問:簡單說說 CompletionService 的作用和使用場景及原理?

答:CompletionService 是一個泛型介面,其實現類是 ExecutorCompletionService,其主要解決的場景是:主執行緒提交多個任務然後希望有任務完成就處理結果,並且按照任務完成順序逐個處理(譬如併發請求返回重新整理 UI 的操作,就可以誰請求成功就開始刷而不用等待所有 OK 才重新整理)。CompletionService 介面如下:

        public interface CompletionService<V> {
            //同執行緒池介面方法含義 

            Future<V> submit(Callable<V> task);

            Future<V> submit(Runnable task, V result);

            // 阻塞等待獲取下一個完成任務的結果 
            Future<V> take() throws InterruptedException;

            // 直接獲取下一個完成任務的結果,如果沒有已經完成的任務則返回null 
            Future<V> poll();

            // 最多等待timeout後返回,如果沒有已經完成的任務則返回null 
            Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;
        }

ExecutorCompletionService 實現類依賴於 Executor 完成實際的任務提交執行,自己主要負責結果的排隊處理,AbstractExecutorService 的 invokAny 實現就依賴此類,ExecutorCompletionService 內部有一個額外的佇列,每個提交給 Executor 的任務都是通過繼承 FutureTask 封裝過的,FutureTask 在任務結束後會回撥 done 方法,所以 ExecutorCompletionService 就在繼承 FutureTask 封裝重寫的 done 方法中,將當前 FutureTask 加入額外佇列,然後我們通過其 take 或者 poll 方法獲取的實質就是從這個額外佇列中取資料。

相關文章