1 線程池的好處
- 線程的創建和銷燬由線程池維護,一個線程在完成任務後並不會立即銷燬,而是由後續的任務複用這個線程,從而減少線程的創建和銷燬,節約系統的開銷。
- 線程池旨在線程的複用,這就可以節約我們用以往方式創建線程和銷燬線程所消耗的時間,減少程序頻繁調度的開銷,從而節約系統資源,提高系統吞吐量。
- 在執行大量異步任務時提高了性能
- Java內置的一套ExecutorService線程池相關的api,可以更方便的控制線程的最大併發數、線程的定時任務、單線程的順序執行等
2 五種線程池的使用場景
- newFixedThreadPool
- 作用:該方法返回一個固定線程數量的線程池,該線程池中的線程數量始終保持不變,即不會再創建新的線程,也不會銷燬已經創建好的線程,自始至終都是那幾個固定的線程在工作,所以該線程池可以控制線程的最大併發數。
- 例子:假如有一個新任務提交時,如果線程池中有空閒的線程,則立即使用空線程來處理任務;如果沒有,則會把這個新任務放在一個任務隊列中,一旦有線程空閒,則按FIFO方式處理任務隊列中的任務。
- 場景:由於該線程池線程數量固定且不被回收,線程與線程池的生命週期同步,所以適用於任務量比較固定但耗時長的任務。
- newCachedThreadPool
- 作用:該方法返回一個可以根據實際情況調整線程池中線程數量的線程池。即該線程池中的線程數量不確定,是根據實際情況動態調整的。
- 例子:假如線程池中的所有線程都正在工作,而此時有新的任務提交,那麼將會創建新線程去處理該任務,而此時假如之前有一些線程完成了任務,現在又有新任務提交,那麼將不會創建新線程去處理,而是複用空閒的線程去處理新任務。線程池中的線程都有個“保持活動時間”的參數,通過配置它,如果線程池中的空閒線程的空閒時間超過該“保持活動時間”,則立即銷燬該線程,線程池默認的“保持活動時間”爲60s
- 場景:因爲該線程池空閒一段時間後就會被回收,所以該線程池比較適合任務量大且耗時短的任務。
- newSingleThreadExecutor
- 作用:該方法返回一個只有一個線程的線程池,即每次只執行一個線程任務,多餘的任務會保存到一個任務隊列中,等待這個線程池空閒,然後再按照FIFO方式順序執行任務隊列中的任務。
- 場景:因爲這個線程池只有一個線程,且沒喫只執行一個線程任務,所以比較適用於多個任務的順序執行的場景。
- newScheduledThreadPool
- 作用:該方法返回一個可以控制線程池內線程定時或週期性執行某任務的線程池。這種線程池核心線程數是固定的,但它的非核心線程是沒有限制的,並且非核心線程一旦閒置就會被回收,keepAliveTime同樣無效,因爲核心線程是不會回收的,當運行的線程數沒有達到corePoolSize的時候,就新建線程去DelayedWorkQueue中取ScheduledFutureTask然後纔去執行任務,否則就把任務添加到DelayedWorkQueue。
- 場景:這類線程池適用於執行定時任務和具體固定週期的重複任務
- newSingleThreadScheduledExecutor
- 作用:該方法返回一個只有一個線程且線程定時或週期性執行某任務的線程池。
- 場景:適用於多個週期任務的順序執行
3 線程池的幾個參數的理解
- keepAliveTime:保持活動時間,線程池中線程空閒最大時長不能超過keepAliveTime,一旦超過keepAliveTime,則線程可能被銷燬(對newScheduledThreadPool無效)
- corePoolSize:核心線程數量
- maximumPoolSize:最大允許線程數量
- keepAliveTime:保持存活時間(如果線程數量大於核心線程數,則多餘空閒線程最大的存活時間,超過該時間,空閒線程將會被銷燬)
- unit:keepAliveTime的時間單位
- workQueue:工作隊列
參考文章:【Android】線程池原理及使用