1. 程式人生 > >(五)java 執行緒池工作佇列

(五)java 執行緒池工作佇列

執行緒池工作佇列

  上一章我們介紹了執行緒的基本情況,這一章進一步瞭解執行緒池中的工作佇列,BlockingQueue 佇列。

在類 Executors 中,我們可以看到不同執行緒池維護的工作佇列是不同的,如newCachedThreadPool使用的是SynchronousQueue 同步佇列,newSingleThreadScheduledExecutor使用DelayedWorkQueue
newFixedThreadPoolnewScheduledThreadPool使用LinkedBlockingQueue。它們都是實現了併發包java.util.concurrent

中的BlockingQueue,下面說說這個介面。

BlockingQueue 阻塞佇列

繼承於佇列 Queue,遵循先進先出原則(FIFO),佇列提供幾種基本的操作,新增元素(隊尾)、移除元素(隊頭)、取出隊頭元素(不移除),每種操作都有兩個方法,一種有可能拋異常,一種返回操作成功或失敗。

在這個基礎上,阻塞佇列增加了操作鎖,保證了資料安全,當然這個具體實現是在子類中完成,介面僅僅描述方法的特點,還增加兩種不同的操作實現。下面描述這四種不同型別的操作:

  1. 操作,可能拋異常
  2. 操作,不拋異常(特殊如類轉換異常、空指標、引數異常不屬於,僅當佇列已滿不會跑狀態異常)
  3. 無限期阻塞執行緒直至操作成功
  4. 有時間限制的操作
新增 移除 檢查
add(e) remove(o) element()
offer(e) poll() peek()
put(e) take() \
offer(e,time,unit) poll(time,unit) \

以及增加了拷貝 drainTo,如執行緒池的 shutdownNow

就是用它完成工作佇列的清除以及佇列中資料的拷貝,還有其他如對比元素contains,剩餘容量查詢remainingCapacity等。

實現的子類

  1. ArrayBlockingQueue 陣列型阻塞佇列
  2. LinkedBlockingQueue 連結串列型阻塞佇列
  3. DelayQueue 延時佇列
  4. SynchronousQueue 同步佇列
  5. PriorityBlockingQueue 優先阻塞佇列

ArrayBlockingQueue

特點:

  1. 初始化一定容量的陣列
  2. 使用一個重入鎖,預設使用非公平鎖,入隊和出隊共用一個鎖,互斥
  3. 是有界設計,如果容量滿無法繼續新增元素直至有元素被移除
  4. 使用時開闢一段連續的記憶體,如果初始化容量過大容易造成資源浪費,過小易新增失敗

LinkedBlockingQueue

特點:

  1. 內部使用節點關聯,會產生多一點記憶體佔用
    • 使用兩個重入鎖分別控制元素的入隊和出隊,用Condition進行執行緒間的喚醒和等待
    • 有邊界的,在預設構造方法中容量是Integer.MAX_VALUE
    • 非連續性記憶體空間
DelayQueue

特點:

  1. 無邊界設計
  2. 新增(put)不阻塞,移除阻塞
  3. 元素都有一個過期時間
  4. 取元素只有過期的才會被取出
SynchronousQueue

特點:

  1. 內部容量是0
  2. 每次刪除操作都要等待插入操作
  3. 每次插入操作都要等待刪除操作
  4. 一個元素,一旦有了插入執行緒和移除執行緒,那麼很快由插入執行緒移交給移除執行緒,這個容器相當於通道,本身不儲存元素
  5. 在多工佇列,是最快的處理任務方式。

一篇關於 SynchronousQueue 的文章

PriorityBlockingQueue

特點:

  1. 無邊界設計,但容量實際是依靠系統資源影響
  2. 新增元素,如果超過1,則進入優先順序排序