BlockingQueue深入分析

2021-09-01 22:11:57 字數 3662 閱讀 3473

1.blockingqueue定義的常用方法如下

丟擲異常

特殊值阻塞

超時插入

add(e)

offer(e)

put(e)

offer(e,time,unit)

移除remove()

poll()

take()

poll(time,unit)

檢查element()

peek()

不可用不可用

1)add(anobject):把anobject加到blockingqueue裡,即如果blockingqueue可以容納,則返回true,否則招聘異常

2)offer(anobject):表示如果可能的話,將anobject加到blockingqueue裡,即如果blockingqueue可以容納,則返回true,否則返回false.

3)put(anobject):把anobject加到blockingqueue裡,如果blockqueue沒有空間,則呼叫此方法的執行緒被阻斷直到blockingqueue裡面有空間再繼續.

4)poll(time):取走blockingqueue裡排在首位的物件,若不能立即取出,則可以等time引數規定的時間,取不到時返回null

5)take():取走blockingqueue裡排在首位的物件,若blockingqueue為空,阻斷進入等待狀態直到blocking有新的物件被加入為止

其中:blockingqueue 不接受null 元素。試圖add、put 或offer 乙個null 元素時,某些實現會丟擲nullpointerexception。null 被用作指示poll 操作失敗的警戒值。 

blockingqueue可以是限定容量的。它在任意給定時間都可以有乙個remainingcapacity,超出此容量,便無法無阻塞地put 附加元素。沒有任何內部容量約束的blockingqueue 總是報告integer.max_value 的剩餘容量。

blockingqueue實現主要用於生產者-使用者佇列,但它另外還支援collection介面。因此,舉例來說,使用remove(x) 從佇列中移除任意乙個元素是有可能的。然而,這種操作通常不 會有效執行,只能有計畫地偶爾使用,比如在取消排隊資訊時。

blockingqueue 實現是執行緒安全的。所有排隊方法都可以使用內部鎖或其他形式的併發控制來自動達到它們的目的。然而,大量的 collection 操作(addall、containsall、retainall 和removeall)沒有 必要自動執行,除非在實現中特別說明。因此,舉例來說,在只新增了c 中的一些元素後,addall(c) 有可能失敗(丟擲乙個異常)。

blockingqueue 實質上不支援使用任何一種「close」或「shutdown」操作來指示不再新增任何項。這種功能的需求和使用有依賴於實現的傾向。例如,一種常用的策略是:對於生產者,插入特殊的end-of-stream 或poison 物件,並根據使用者獲取這些物件的時間來對它們進行解釋。

3、簡要概述blockingqueue常用的四個實現類

1)arrayblockingqueue:規定大小的blockingqueue,其建構函式必須帶乙個int引數來指明其大小.其所含的物件是以fifo(先入先出)順序排序的.

2)linkedblockingqueue:大小不定的blockingqueue,若其建構函式帶乙個規定大小的引數,生成的blockingqueue有大小限制,若不帶大小引數,所生成的blockingqueue的大小由integer.max_value來決定.其所含的物件是以fifo(先入先出)順序排序的

3)priorityblockingqueue:類似於linkedblockqueue,但其所含物件的排序不是fifo,而是依據物件的自然排序順序或者是建構函式的comparator決定的順序.

4)synchronousqueue:特殊的blockingqueue,對其的操作必須是放和取交替完成的.

下面主要看一下

arrayblockingqueue的原始碼:

public

boolean

offer

(e e)

} finally

}

看insert方法:

private

void

insert

(e x)

這裡可以看出arrayblockingqueue採用從前到後向內部陣列插入的方式插入新元素的。如果插完了,putindex可能重新變為0(在已經執行了移除操作的前提下,否則在之前的判斷中隊列為滿)

*/putindex = inc(putindex);

++count;

notempty.signal();

//wake up one waiting thread

}

public

void

put(e e)

throws interruptedexception

catch (interruptedexception ie)

insert(e);

} finally

}

public

boolean

offer

(e e, long timeout, timeunit unit)

throws interruptedexception

if (nanos <=

0)

return

false;

try

catch (interruptedexception ie)

}

} finally

}

public

boolean

add(e e)

父類:

public

boolean

add(e e)

該類中有幾個例項變數:

takeindex/putindex/count

用三個數字來維護這個佇列中的資料變更:

/** items index for next take, poll or remove */

private

int takeindex;

/** items index for next put, offer, or add. */

private

int putindex;

/** number of items in the queue */

private

int count;

**:

阻塞佇列BlockingQueue

例介紹乙個特殊的佇列 blockingqueue,如果blockingqueue是空的,從blockingqueue取東西的操作將會被阻斷進入等待狀態,直到blockingqueue進了東西才會被喚醒,同樣,如果blockingqueue是滿的,任何試圖往裡存東西的操作也會被阻斷進入等待狀態,直到b...

其他幾種BlockingQueue

priorityblockingqueue是一種基於優先順序的阻塞佇列,優先順序的判斷通過建構函式傳入compator物件來決定,也就是說傳入佇列的物件必須實現comparable介面 在實現priorityblockingqueue時,內部控制線程同步的鎖採用的是公平鎖。然後這個容器在新增物件的時...

BlockingQueue 介面詳解

array blocking queue 是基於陣列的阻塞佇列實現,在 arrayblockingqueue 內部,維護乙個定長陣列,以便快取佇列中的資料物件,內部沒有實現讀寫分離,也就意味著生產者和消費者不能完全並行,長度是需要定義的,可以指定先進先出,或者先進後出,也叫有界佇列 linked b...