天天看點

線程池常用的阻塞隊列有哪些?線程池常用的阻塞隊列有哪些?

線程池常用的阻塞隊列有哪些?

文章目錄

  • 線程池常用的阻塞隊列有哪些?
    • 1.線程池的内部結構
    • 2.阻塞隊列
    • 3.LinkedBlockingQueue
    • 4.SynchronousQueue
    • 5.DelayedWorkQueue
    • 6.參考

1.線程池的内部結構

線程池常用的阻塞隊列有哪些?線程池常用的阻塞隊列有哪些?

線程池内部由四部分組成

  • 第一部分是線程池管理器,主要負責管理線程池的建立、銷毀、添加任務等管理操作。
  • 第二部分是工作線程,它又分為核心工作線程和非核心工作線程。
  • 第三部分是任務隊列,作為一種緩沖機制,會将超過核心線程數的任務放到任務隊列中,等待執行;由于多線程同時從任務隊列中擷取任務是并發場景,此時就需要任務隊列滿足線程安全的要求,是以線程池中任務隊列采用 BlockingQueue 來保障線程安全。
  • 第四部分是任務,任務要求實作統一的接口,以便工作線程可以處理和執行。

2.阻塞隊列

線程池對應的阻塞隊列

線程池 阻塞隊列
FixedThreadPool LinkedBlockingQueue
SingleThreadExecutor LinkedBlockingQueue
CachedThreadPool SynchronousQueue
ScheduledThreadPool DelayedWorkQueue
SingleThreadScheduledExecutor DelayedWorkQueue

3.LinkedBlockingQueue

第一種阻塞隊列是 LinkedBlockingQueue,它的容量是 Integer.MAX_VALUE,為 231 -1 ,是一個非常大的值,可以認為是無界隊列。

FixedThreadPool 和 SingleThreadExecutor 線程池的線程數是固定的,是以沒有辦法增加特别多的線程來處理任務,這時就需要 LinkedBlockingQueue 這樣一個沒有容量限制的阻塞隊列來存放任務。

4.SynchronousQueue

第二種阻塞隊列是 SynchronousQueue,對應的線程池是 CachedThreadPool。線程池 CachedThreadPool 的最大線程數是 Integer.MAX_VALUE,可以了解為線程數是可以無限擴充的。

CachedThreadPool 和上一種線程池 FixedThreadPool 的情況恰恰相反,FixedThreadPool 的情況是阻塞隊列的容量是無限的,而這裡 CachedThreadPool 是線程數可以無限擴充,是以 CachedThreadPool 線程池并不需要一個任務隊列來存儲任務,因為一旦有任務被送出就直接轉發給線程或者建立新線程來執行,而不需要另外儲存它們。

我們自己建立使用 SynchronousQueue 的線程池時,如果不希望任務被拒絕,那麼就需要注意設定最大線程數要盡可能大一些,以免發生任務數大于最大線程數時,沒辦法把任務放到隊列中也沒有足夠線程來執行任務的情況。

5.DelayedWorkQueue

第三種阻塞隊列是DelayedWorkQueue,它對應的線程池分别是 ScheduledThreadPool 和 SingleThreadScheduledExecutor,這兩種線程池的最大特點就是可以延遲執行任務,比如說一定時間後執行任務或是每隔一定的時間執行一次任務。

DelayedWorkQueue 的特點是内部元素并不是按照放入的時間排序,而是會按照延遲的時間長短對任務進行排序,内部采用的是“堆”的資料結構(堆的應用之一就是 優先級隊列)。之是以線程池 ScheduledThreadPool 和 SingleThreadScheduledExecutor 選擇 DelayedWorkQueue,是因為它們本身正是基于時間執行任務的,而延遲隊列正好可以把任務按時間進行排序,友善任務的執行。

6.參考

  • 《Java 并發程式設計 78 講》- 徐隆曦

繼續閱讀