1. 程式人生 > >執行緒池原理--任務佇列BlockingQueue

執行緒池原理--任務佇列BlockingQueue

文章目錄


執行緒池原理–總索引

執行緒池原理–任務佇列BlockingQueue

類繼承體系

在這裡插入圖片描述
BlockingQueue不能夠新增null物件,否則會丟擲空指標異常。

介面抽象方法

  • boolean add(E e);
    新增元素,新增成功返回true ,新增失敗丟擲異常 IllegalStateException。
  • boolean offer(E e);
    true:新增元素成功 ; false : 新增元素失敗。
  • void put(E e) throws InterruptedException;
    新增元素,直到有空間新增成功才會返回,阻塞方法。
  • boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
    true:新增資料成功,false:超時時間到。
  • E take() throws InterruptedException;
    獲取隊頭的元素,阻塞方法,會一直等到有元素獲取到才會返回,獲取到元素時並將佇列中的該元素刪除。
  • E poll(long timeout, TimeUnit unit) throws InterruptedException;
    獲取隊頭的元素,阻塞方法,超時時間到則返回null,獲取到元素時並將佇列中的該元素刪除。
  • int remainingCapacity();
    返回理想情況下此佇列可以新增的其他元素的數量.
  • boolean remove(Object o);
    移除指定的元素。
  • boolean contains(Object o);
    檢查是否包含該元素
  • int drainTo(Collection<? super E> c);
    移除佇列中的所有元素並新增到集合c,返回被移除元素的數量。
  • int drainTo(Collection<? super E> c, int maxElements);
    移除佇列中maxElements個元素並新增到集合c,返回被移除元素的數量。

實現類

所有的實現類都是併發安全的。

ArrayBlockingQueue

ArrayBlockingQueue 是 BlockingQueue 介面的有界佇列實現類,底層採用陣列來實現。其併發控制採用可重入鎖來控制,不管是插入操作還是讀取操作,都需要獲取到鎖才能進行操作。

SynchronousQueue

它是一個特殊的佇列,它的名字其實就蘊含了它的特徵 – - 同步的佇列。為什麼說是同步的呢?這裡說的並不是多執行緒的併發問題,而是因為當一個執行緒往佇列中寫入一個元素時,寫入操作不會立即返回,需要等待另一個執行緒來將這個元素拿走;同理,當一個讀執行緒做讀操作的時候,同樣需要一個相匹配的寫執行緒的寫操作。這裡的 Synchronous 指的就是讀執行緒和寫執行緒需要同步,一個讀執行緒匹配一個寫執行緒。

LinkedBlockingDeque

LinkedBlockingDeque就是一個雙向佇列,任何一端都可以進行元素的出入。底層基於單向連結串列實現的阻塞佇列,可以當做無界佇列也可以當做有界佇列來使用。

LinkedBlockingQueue

LinkedBlockingQueue是一個單向佇列,只能一端出一端入的單向佇列結構,是有FIFO特性的,並且是通過兩個ReentrantLock和兩個Condition來實現的。底層基於單向連結串列實現的阻塞佇列,可以當做無界佇列也可以當做有界佇列來使用。

DelayQueue

是一個支援延時獲取元素的無界阻塞佇列。內部用 PriorityQueue 實現。

LinkedTransferQueue

PriorityBlockingQueue

PriorityBlockingQueue是帶排序的 BlockingQueue 實現,其併發控制採用的是 ReentrantLock,佇列為無界佇列(ArrayBlockingQueue 是有界佇列,LinkedBlockingQueue 也可以通過在建構函式中傳入 capacity 指定佇列最大的容量,但是 PriorityBlockingQueue 只能指定初始的佇列大小,後面插入元素的時候,如果空間不夠的話會自動擴容)。

簡單地說,它就是 PriorityQueue 的執行緒安全版本。不可以插入 null 值,同時,插入佇列的物件必須是可比較大小的(comparable),否則報 ClassCastException 異常。它的插入操作 put 方法不會 block,因為它是無界佇列(take 方法在佇列為空的時候會阻塞)。