Android中的執行緒池

quincy發表於2018-05-26

為什麼使用執行緒池?

1、重用執行緒,防止頻繁的建立銷燬執行緒所帶來的時間和資源等效能損耗。
2、有效的控制最大執行緒併發數,防止大量執行緒搶奪系統資源引起卡頓,合理利用系統資源。
3、對執行緒進行簡單管理、以及執行緒間更好的協作工作

Android 中有哪幾種執行緒池?

實際意義上我們所說的幾種常用執行緒池都是 Java 封裝好,都在 Executors 這個工廠類裡面了,筆者使用的是 JDK8 所以發現裡面有六種執行緒池,接下來分別介紹下

1. FixedThreadPool

數量固定的核心執行緒池,當執行緒池處於空閒時執行緒也不會被回收,除非執行緒被關閉了。如果所有執行緒都在執行中,再有新任務新增時新任務會處於等在狀態,知道有執行緒空閒在執行。處於等待的任務沒有數量上限

2. CachedThreadPool

這是一種執行緒數量不定的執行緒池,他只有非核心執行緒,執行緒池如果沒有空閒執行緒,會隨時建立新的執行緒來工作,如果空下來的執行緒空閒時長超過 60 秒,則會被回收。他在長時間不工作的時候內部是沒有任何執行緒的,也就是不消耗任何資源

3. SingleThreadExecutor

只有一個核心執行緒的執行緒池,所有任務都要排隊等待由唯一的一個核心執行緒來處理,處於等待的任務佇列個數沒有上限

4. ScheduledThreadPool

這是一個核心執行緒數量固定,非核心執行緒沒有上限的執行緒池,非核心執行緒閒置時間超過 10 秒就會被回收(不同版本 JDK 可能不同),並且他的等待佇列只有 16 個。並且支援定時及週期性任務執行。

5. SingleThreadScheduledExecutor

就是一個只有一個核心執行緒的 ScheduledThreadPool 執行緒池

6. WorkStealingPool

建立持有足夠執行緒的執行緒池來支援給定的並行級別,並通過使用多個佇列,減少競爭,它需要傳一個並行數量,如果不傳,則被設定為預設的CPU數量

自定義執行緒池

接下來上面提到的核心執行緒、非核心執行緒是什麼,還有上面執行緒池的實現。
上面所有的執行緒池都是通過以下兩個類建立的

一、 先說一說 ThreadPoolExecutor

public ThreadPoolExecutor(
    int corePoolSize,
    int maximumPoolSize,
    long keepAliveTime,
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue) {
         this(corePoolSize, 
             maximumPoolSize, 
             keepAliveTime, 
             unit, 
             workQueue,
             Executors.defaultThreadFactory(), 
             defaultHandler);
}

看一看各項引數

  • corePoolSize:執行緒池的核心執行緒數
  • maximumPoolSize:執行緒池中允許的最大執行緒數(maximumPoolSize-corePoolSize = 非核心執行緒)
  • keepAliveTime:空閒執行緒結束的超時時間(如果 allowCoreThreadTimeOut 屬性設定為 true 核心執行緒閒置 keepAliveTime 時間以上也會被回收,false 則不會回收)
  • unit:是一個列舉,它表示的是 keepAliveTime 的單位
  • workQueue:工作佇列,用於任務的存放

執行流程

  1. 執行緒池建立的時候裡面不會有任何執行緒
  2. 如果正在執行的執行緒數量小於 corePoolSize,那麼馬上建立執行緒執行這個任務;
  3. 如果正在執行的執行緒數量大於或等於 corePoolSize,那麼將這個任務放入佇列;
  4. 如果這時候佇列滿了,而且正在執行的執行緒數量小於 maximumPoolSize,那麼還是要建立非核心執行緒立刻執行這個任務;
  5. 如果佇列滿了,而且正在執行的執行緒數量大於或等於 maximumPoolSize,那麼執行緒池會丟擲異常RejectExecutionException。

我們上面說的 FixedThreadPool、CachedThreadPool、SingleThreadExecutor、ScheduledThreadPool、SingleThreadScheduledExecutor 都是通過 ThreadPoolExecutor 建立的,好奇的人可以看一下原始碼。

二、 ForkJoinPool

ForkJoinPool 是JDK 7加入的一個執行緒池類。Fork/Join 技術是分治演算法(Divide-and-Conquer)的並行實現,它是一項可以獲得良好的並行效能的簡單且高效的設計技術。目的是為了幫助我們更好地利用多處理器帶來的好處,使用所有可用的運算能力來提升應用的效能。我們常用的陣列工具類 Arrays 在JDK 8之後新增的並行排序方法(parallelSort)就運用了 ForkJoinPool 的特性,還有 ConcurrentHashMap 在JDK 8之後新增的函式式方法(如forEach等)也有運用。

我們上面說的 WorkStealingPool 都是通過 ForkJoinPool 建立的。

這個知識點比較複雜大家可以參考其他部落格


相關文章