天天看點

Android 中的線程池為什麼使用線程池?Android 中有哪幾種線程池?自定義線程池

為什麼使用線程池?

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 建立的。

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

繼續閱讀