06.09 線程池原理分析

摘要

首先要明確為什麼要使用線程池,使用線程池會帶來什麼好處?

  • 線程是稀缺資源,不能頻繁的創建。
  • 應當將其放入一個池子中,可以給其他任務進行復用。
  • 解耦作用,線程的創建與執行完全分開,方便維護。

創建一個線程池

以一個使用較多的

ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<runnable> workQueue, RejectedExecutionHandler handler) 
/<runnable>

參數說明:

  • 其中的 corePoolSize 為線程池的基本大小。
  • maximumPoolSize 為線程池最大線程大小。
  • keepAliveTime 和 unit 則是線程空閒後的存活時間。
  • workQueue 用於存放任務的阻塞隊列。
  • handler 當隊列和最大線程池都滿了之後的飽和策略。

處理流程

當提交一個任務到線程池時它的執行流程是怎樣的呢?

線程池原理分析

首先第一步會判斷核心線程數有沒有達到上限,如果沒有則創建線程(會獲取全局鎖),滿了則會將任務丟進阻塞隊列。

如果隊列也滿了則需要判斷最大線程數是否達到上限,如果沒有則創建線程(獲取全局鎖),如果最大線程數也滿了則會根據飽和策略處理。

常用的飽和策略有:

  • 直接丟棄任務。
  • 調用者線程處理。
  • 丟棄隊列中的最近任務,執行當前任務。

所以當線程池完成預熱之後都是將任務放入隊列,接著由工作線程一個個從隊列裡取出執行。

合理配置線程池

線程池並不是配置越大越好,而是要根據任務的熟悉來進行劃分: 如果是 CPU 密集型任務應當分配較少的線程,比如 CPU 個數相當的大小。

如果是 IO 密集型任務,由於線程並不是一直在運行,所以可以儘可能的多配置線程,比如 CPU 個數 * 2 。

當是一個混合型任務,可以將其拆分為 CPU 密集型任務以及 IO 密集型任務,這樣來分別配置。

更多內容請關注每日編程,每天進步一點。


分享到:


相關文章: