一、BlockingQueued
BlockingQueued 隊列使用 ReentrantLock 和 Condition(AQS實現)來實現的。Condition 只能用於獨占模式。
條件隊列中的節點永遠不會被喚醒,一直阻塞者;要想喚醒,則需要把該節點放到CLH隊列中,放入到CLH隊列中才有機會去競爭、喚醒;
條件隊列是單向鏈表,CLH隊列為雙向鏈表。
首先看一下 BlockingQueued 的源碼:
public interface BlockingQueue<E> extends Queue<E> {
//將給定元素設置到隊列中,如果設置成功返回true, 否則返回false。如果是往限定了長度的隊列中設置值,推薦使用offer()方法。
boolean add(E e);
//將給定的元素設置到隊列中,如果設置成功返回true, 否則返回false. e的值不能為空,否則拋出空指針異常。
boolean offer(E e);
//將元素設置到隊列中,如果隊列中沒有多余的空間,該方法會一直阻塞,直到隊列中有多余的空間。
void put(E e) throws InterruptedException;
//將給定元素在給定的時間內設置到隊列中,如果設置成功返回true, 否則返回false.
boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;
//從隊列中獲取值,如果隊列中沒有值,線程會一直阻塞,直到隊列中有值,並且該方法取得了該值。
E take() throws InterruptedException;
//在給定的時間里,從隊列中獲取值,時間到了直接調用普通的poll方法,為null則直接返回null。
E poll(long timeout, TimeUnit unit)
throws InterruptedException;
//獲取隊列中剩余的空間。
int remainingCapacity();
//從隊列中移除指定的值。
boolean remove(Object o);
//判斷隊列中是否擁有該值。
public boolean contains(Object o);
//將隊列中值,全部移除,並發設置到給定的集合中。
int drainTo(Collection<? super E> c);
//指定最多數量限制將隊列中值,全部移除,並發設置到給定的集合中。
int drainTo(Collection<? super E> c, int maxElements);
}
1. ArrayBlockingQueued
由數組支持的有界隊列;容量大小在創建ArrayBlockingQueue對象時已定義好。默認情況下不保證線程公平的訪問隊列。
分析源碼;
2. LinkedBlockingQueue
由鏈接節點支持的可選有界隊列;此隊列的默認和最大長度為 Integer.MAX_VALUE。
3. PriorityBlockingQueue
由優先級堆支持的無界優先級隊列;
默認情況下元素采取自然順序升序排列。也可以自定義類實現compareTo()方法來指定元素排序規則,或者初始化PriorityBlockingQueue時,指定構造參數Comparator來對元素進行排序。需要注意的是不能保證同優先級元素的順序。
4. DelayQueue
由優先級隊列支持的、基於時間的調度隊列,內部基於無界隊列PriorityQueue實現,而無界隊列基於數組的擴容實現。
隊列中的元素必須實現Delayed接口,在創建元素時可以指定多久才能從隊列中獲取當前元素。只有在延遲期滿時才能從隊列中提取元素。
5. SynchronousQueue
SynchronousQueue是一個不存儲元素的阻塞隊列。每一個put操作必須等待一個take操作,否則不能繼續添加元素。
它支持公平訪問隊列。默認情況下線程采用非公平性策略訪問隊列。使用以下構造方法可以創建公平性訪問的SynchronousQueue,如果設置為true,則等待的線程會采用先進先出的順序訪問隊列。
6.LinkedTransferQueue
LinkedTransferQueue是一個由鏈表結構組成的無界阻塞TransferQueue隊列。相對於其他阻塞隊列,LinkedTransferQueue多了tryTransfer和transfer方法。
(1)transfer方法
如果當前有消費者正在等待接收元素(消費者使用take()方法或帶時間限制的poll()方法時),transfer方法可以把生產者傳入的元素立刻transfer(傳輸)給消費者。如果沒有消費者在等待接收元素,transfer方法會將元素存放在隊列的tail節點,並等到該元素被消費者消費了才返回。
(2)tryTransfer方法
tryTransfer方法是用來試探生產者傳入的元素是否能直接傳給消費者。如果沒有消費者等待接收元素,則返回false。和transfer方法的區別是tryTransfer方法無論消費者是否接收,方法立即返回,而transfer方法是必須等到消費者消費了才返回。
7.LinkedBlockingDeque
LinkedBlockingDeque是一個由鏈表結構組成的雙向阻塞隊列。所謂雙向隊列指的是可以從隊列的兩端插入和移出元素。雙向隊列因為多了一個操作隊列的入口,在多線程同時入隊時,也就減少了一半的競爭。相比其他的阻塞隊列,LinkedBlockingDeque多了addFirst、addLast、offerFirst、offerLast、peekFirst和peekLast等方法,以First單詞結尾的方法,表示插入、獲取(peek)或移除雙端隊列的第一個元素。以Last單詞結尾的方法,表示插入、獲取或移除雙端隊列的最后一個元素。另外,插入方法add等同於addLast,移除方法remove等效於removeFirst。但是take方法卻等同於takeFirst,不知道是不是JDK的bug,使用時還是用帶有First和Last后綴的方法更清楚。
參考鏈接:https://www.cnblogs.com/WangHaiMing/p/8798709.html