1. 程式人生 > 其它 >【博學谷學習記錄】超強總結,用心分享。執行緒池重難點知識

【博學谷學習記錄】超強總結,用心分享。執行緒池重難點知識

 執行緒池

1.1       為什麼需要執行緒池 

在實際使用中,執行緒是很佔用系統資源的,如果對執行緒管理不完善的話很容易導致系統問題。因此,在大多數併發框架中都會使用執行緒池來管理執行緒,使用執行緒池管理執行緒主要有如下好處:


1、使用執行緒池可以重複利用已有的執行緒繼續執行任務,避免執行緒在建立銷燬時造成的消耗

2、由於沒有執行緒建立和銷燬時的消耗,可以提高系統響應速度

3、通過執行緒可以對執行緒進行合理的管理,根據系統的承受能力調整可執行執行緒數量的大小等

1.2       執行緒池的分類


  1. newCachedThreadPool:建立一個可進行快取重複利用的執行緒池
  2. newFixedThreadPool:建立一個可重用固定執行緒數的執行緒池,以共享的無界佇列方式來執行這些執行緒,執行緒池中的執行緒處於一定的量,可以很好的控制執行緒的併發量
  3. newSingleThreadExecutor : 創 建 一 個 使 用 單 個 worker 線 程 的 Executor ,以無界佇列方式來執行該執行緒。執行緒池中最多執行一個執行緒,之後提交的執行緒將會排在佇列中以此執行
  4. newSingleThreadScheduledExecutor:建立一個單執行緒執行程式,它可安排在給定延遲後執行命令或者定期執行
  5. newScheduledThreadPool:建立一個執行緒池,它可安排在給定延遲後執行命令或者定期的執行
  6. newWorkStealingPool:建立一個帶並行級別的執行緒池,並行級別決定了同一時刻最多有多少個執行緒在執行,如不傳並行級別引數,將預設為當前系統的 CPU 個數

1.3       核心引數

corePoolSize:核心執行緒池的大小 maximumPoolSize:執行緒池能建立執行緒的最大個數 keepAliveTime:空閒執行緒存活時間

unit:時間單位,為 keepAliveTime 指定時間單位

workQueue:阻塞佇列,用於儲存任務的阻塞佇列

threadFactory:建立執行緒的工程類

handler:飽和策略(拒絕策略)

1.4       執行緒池的原理


 
執行緒池的工作過程如下:

當一個任務提交至執行緒池之後,

  1. 執行緒池首先判斷核心執行緒池裡的執行緒是否已經滿了。如果不是,則建立一個新的工作執行緒來執行任務。否則進入 
    1. 判斷工作佇列是否已經滿了,倘若還沒有滿,將執行緒放入工作佇列。否則進入  
    2. 判斷執行緒池裡的執行緒是否都在執行任務。如果不是,則建立一個新的工作執行緒來執行。如果執行緒池滿了,則交給飽和策略來處理任務。

4.5       拒絕策略

ThreadPoolExecutor.AbortPolicy(系統預設): 丟棄任務並丟擲 RejectedExecutionException 異常,讓你感知到任務被拒絕了,我們可以根據業務邏輯選擇重試或者放棄提交等策略

ThreadPoolExecutor.DiscardPolicy: 也是丟棄任務,但是不丟擲異常,相對而言存在一定的風險,因為我們提交的時候根本不知道這個任務會被丟棄,可能造成資料丟失。  ThreadPoolExecutor.DiscardOldestPolicy: 丟棄佇列最前面的任務,然後重新嘗試執行任務(重複此過程),通常是存活時間最長的任務,它也存在一定的資料丟失風險 ThreadPoolExecutor.CallerRunsPolicy:既不拋棄任務也不丟擲異常,而是將某些任務回退到呼叫者,讓呼叫者去執行它。

4.6       執行緒池的關閉

關閉執行緒池,可以通過 shutdown 和 shutdownNow 兩個方法原理:遍歷執行緒池中的所有執行緒,然後依次中斷

1、shutdownNow 首先將執行緒池的狀態設定為 STOP,然後嘗試停止所有的正在執行和未執行任務的執行緒,並返回等待執行任務的列表;

2、shutdown 只是將執行緒池的狀態設定為 SHUTDOWN 狀態,然後中斷所有沒有正在執行任務的執行緒