Java 集合系列之四:Queue基本操做

1. Java Queue

1. Java Queue 重要觀點

  • Java Queue接口是Java Collections Framework的成員。
  • Queue 實現一般不容許插入 null 元素
  • 隊列一般(但並不是必定)以 FIFO(先進先出)的方式排序各個元素。不過優先級隊列和 LIFO 隊列(或堆棧)例外,前者根據提供的比較器或元素的天然順序對元素進行排序,後者按 LIFO(後進先出)的方式對元素進行排序。不管使用哪一種排序方式,隊列的 都是調用 remove() 或 poll() 所移除的元素。在 FIFO 隊列中,全部的新元素都插入隊列的末尾。其餘種類的隊列可能使用不一樣的元素放置規則。每一個 Queue 實現必須指定其順序屬性。
  • 在處理元素前用於保存元素的 collection。除了基本的 Collection 操做外,隊列還提供其餘的插入、提取和檢查操做。每一個方法都存在兩種形式:一種拋出異常(操做失敗時),另外一種返回一個特殊值(null 或 false,具體取決於操做)。
  • Queue 接口並未定義阻塞隊列的方法,而這在併發編程中是很常見的。BlockingQueue 接口定義了那些等待元素出現或等待隊列中有可用空間的方法,這些方法擴展了此接口。
  •   拋出異常   返回特殊值
    插入:add(e)     offer(e)  插入一個元素
    移除:remove()      poll()      移除和返回隊列的頭
    檢查:element()     peek()    返回但不移除隊列的頭。html

  • JDK中併發隊列提供了兩種實現,一種是高性能隊列ConcurrentLinkedQueue,一種是阻塞隊列BlockingQueue(7種阻塞隊列),兩種都繼承自Queue。
  • JDK中隊列有兩大類,一類是雙端隊列,一類是單端隊列。

2. Java Queue類圖

此接口是 Java Collections Framework 的成員。java

Java Queue接口擴展了Collection接口。Collection接口 externs Iterable接口。算法

子接口:BlockingQueue, Deque, BlobkingDequeue編程

一些最經常使用的Queue實現類是LinkedList,ArrayBlickingQueue, LinkedBlockingQueue,PriorityQueue, PriorityBlockingQueue。api

3. Java Queue 方法

boolean  add(E e) //將指定的元素插入此隊列(若是當即可行且不會違反容量限制),在成功時返回 true,若是當前沒有可用的空間,則拋出 IllegalStateException。
E        element() //獲取,可是不移除此隊列的頭。
boolean  offer(E e) //將指定的元素插入此隊列(若是當即可行且不會違反容量限制),當使用有容量限制的隊列時,此方法一般要優於 add(E),後者可能沒法插入元素,而只是拋出一個異常。
E        peek() //獲取但不移除此隊列的頭;若是此隊列爲空,則返回 null。
E        poll() //獲取並移除此隊列的頭,若是此隊列爲空,則返回 null。
E        remove() //獲取並移除此隊列的頭。

2. ConcurrentLinkedQueue接口(JUC)

1. ConcurrentLinkedQueue 結構圖

一個基於連接節點的無界線程安全隊列。數組

2. ConcurrentLinkedQueue重要特色

  1. 一個基於連接節點的無界線程安全隊列。此隊列按照 FIFO(先進先出)原則對元素進行排序。隊列的頭部 是隊列中時間最長的元素。隊列的尾部是隊列中時間最短的元素。新的元素插入到隊列的尾部,隊列獲取操做從隊列頭部得到元素。當多個線程共享訪問一個公共 collection 時,ConcurrentLinkedQueue 是一個恰當的選擇。緩存

  2. 此隊列不容許使用 null 元素。安全

  3. 此實現採用了有效的「無等待 (wait-free)」算法,該算法基於 Maged M. Michael 和 Michael L. Scott 合著的 Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue Algorithms 中描述的算法。數據結構

  4. 須要當心的是,與大多數 collection 不一樣,size 方法不是 一個固定時間操做。因爲這些隊列的異步特性,肯定當前元素的數量須要遍歷這些元素。多線程

  5. 內存一致性效果:當存在其餘併發 collection 時,將對象放入 ConcurrentLinkedQueue 以前的線程中的操做 happen-before 隨後經過另外一線程從 ConcurrentLinkedQueue 訪問或移除該元素的操做。
  6. ConcurrentLinkedQueue中有兩個volatile類型的Node節點分別用來存在列表的首尾節點,其中head節點存放鏈表第一個item爲null的節點,tail則並非總指向最後一個節點。Node節點內部則維護一個變量item用來存放節點的值,next用來存放下一個節點,從而連接爲一個單向無界列表。
  7. 開源框架中使用:Tomcat中NioEndPoint中的每一個poller裏面就維護一個ConcurrentLinkedQueue<Runnable>用來做爲緩衝存聽任務。
  8. ConcurrentLinkedQueue使用CAS非阻塞算法實現使用CAS解決了當前節點與next節點之間的安全連接和對當前節點值的賦值。【CAS的基本思想是認爲當前環境中的併發並無那麼高,比較樂觀的看待整個併發,只須要在更新某個值時先檢查下該值有沒有發生變化,若是沒有發生變化則更新,不然放棄更新。CAS的操做其底層是經過調用sun.misc.Unsafe類中的CompareAndSwap的方法保證線程安全的。】因爲使用CAS沒有使用鎖,因此獲取size的時候有可能進行offer,poll或者remove操做,致使獲取的元素個數不精確,因此在併發狀況下size函數不是頗有用。另外第一次peek或者first時候會把head指向第一個真正的隊列元素。
  9. 線程安全的volatile + CAS 可知入隊出隊函數都是操做volatile變量:head,tail因此要保證隊列線程安全只須要保證對這兩個Node操做的可見性和原子性,因爲volatile自己保證可見性,因此只須要看下多線程下若是保證對着兩個變量操做的原子性。對於offer操做是在tail後面添加元素,也就是調用tail.casNext方法,而這個方法是使用的CAS操做,只有一個線程會成功,而後失敗的線程會循環一下,從新獲取tail,而後執行casNext方法。對於poll也是這樣的。

3. Deque接口

1. Deque結構圖

 

  一個線性 collection,支持在兩端插入和移除元素。名稱 deque 是「double ended queue(雙端隊列)」的縮寫,一般讀爲「deck」。大多數 Deque 實現對於它們可以包含的元素數沒有固定限制,但此接口既支持有容量限制的雙端隊列,也支持沒有固定大小限制的雙端隊列。

  隊列:此接口擴展了 Queue 接口。在將雙端隊列用做隊列時,將獲得 FIFO(先進先出)行爲。將元素添加到雙端隊列的末尾,從雙端隊列的開頭移除元素。

  堆棧:雙端隊列也可用做 LIFO(後進先出)堆棧。應優先使用此接口而不是遺留 Stack 類。在將雙端隊列用做堆棧時,元素被推入雙端隊列的開頭並從雙端隊列開頭彈出。堆棧方法徹底等效於 Deque 方法,

4. LinkedList

1. LinkedList 結構圖

LinkedList是基於鏈表實現的,從源碼能夠看出是一個雙向鏈表。除了當作鏈表使用外,它也能夠被看成堆棧、隊列或雙端隊列進行操做

LinkedList不是線程安全的,繼承AbstractSequentialList實現List、Deque、Cloneable、Serializable。

  • LinkedList繼承AbstractSequentialList,AbstractSequentialList 實現了get(int index)、set(int index, E element)、add(int index, E element) 和 remove(int index)這些函數。這些接口都是隨機訪問List的。
  • LinkedList 實現 List 接口,能對它進行隊列操做。
  • LinkedList 實現 Deque 接口,即能將LinkedList看成雙端隊列使用。
  • LinkedList 實現了Cloneable接口,即覆蓋了函數clone(),能克隆。
  • LinkedList 實現java.io.Serializable接口,這意味着LinkedList支持序列化,能經過序列化去傳輸。

2. LinkedList 重要特色

  1. 本質實現:底層使用一個Node數據結構,有先後兩個指針,雙向鏈表實現。
  2. 線程安全:非同步的。
  3. 列表長度:LinkedList中元素個數用size記錄。
  4. 列表容量:LinkedList是基於鏈表實現的,所以不存在容量不足的問題,因此這裏沒有擴容的方法。
  5. 內存:須要更多的內存,LinkedList 每一個節點中須要多存儲先後節點的信息,佔用空間更多些(previous  element next)。
  6. 元素容許爲null。
  7. Fail-Fast機制:同ArrayList相同。
  8. 遍歷方法:全部指定位置的操做都是從頭開始遍歷進行的。LinkedList是基於鏈表實現的,所以插入刪除效率高,查找效率低(雖然有一個加速動做)。源碼中先將index與長度size的一半比較,若是index<size/2,就只從位置0日後遍歷到位置index處,而若是index>size/2,就只從位置size往前遍歷到位置index處。這樣能夠減小一部分沒必要要的遍歷,從而提升必定的效率(實際上效率仍是很低)。Arrays.copyOf() 方法:
  9. 它適合刪除,插入較多的場景。

5. ConcurrentLinkedDeque接口(JUC)

1. ConcurrentLinkedDeque 結構圖

併發隊列ConcurrentLinkedDeque,這是一個非阻塞,無鎖,無界 ,線程安全雙端操做的隊列。簡單說就是ConcurrentLinkedQueue的升級版,在JDK7以後才提供。該隊列也不容許空元素,並且size方法並非常量時間,其須要遍歷鏈表,此時併發修改鏈表會形成統計size不正確。一樣,bulk操做和equal以及toArray方法不保證原子性。

2. ConcurrentLinkedDeque重要特色

  1. ConcurrentLinkedDeque 是 雙向鏈表結構的無界併發隊列。從JDK 7開始加入到J.U.C的行列中。
  2. 使用 CAS實現併發安全,與 ConcurrentLinkedQueue 的區別是 該阻塞隊列同時支持FIFOFILO兩種操做方式,便可以從隊列的頭和尾同時操做(插入/刪除)。
  3. 適合「多生產,多消費」的場景
  4. 內存一致性遵循對 ConcurrentLinkedDeque 的插入操做先行發生於(happen-before)訪問或移除操做

6. BlockingQueue接口(JUC)

1. BlockingQueue 結構圖

JDK7提供了7個阻塞隊列。分別是

  • ArrayBlockingQueue :一個由數組結構組成的有界阻塞隊列。
  • LinkedBlockingQueue :一個由鏈表結構組成的可選有界阻塞隊列。若是未指定容量,那麼容量將等於 Integer.MAX_VALUE。 2 31-1 
  • PriorityBlockingQueue :一個支持優先級排序的無界阻塞隊列。
  • DelayQueue:一個使用優先級隊列實現的無界阻塞隊列,,只有在延遲期滿時才能從中提取元素。
  • SynchronousQueue:一個不存儲元素、沒有內部容量的阻塞隊列。
  • LinkedTransferQueue:一個由鏈表結構組成的無界阻塞TransferQueue隊列。
  • LinkedBlockingDeque:一個由鏈表結構組成的可選範圍雙向阻塞隊列。若是未指定容量,那麼容量將等於 Integer.MAX_VALUE。 2 31-1 

2. BlockingQueue重要特色

  1. 支持兩個附加操做的 Queue,這兩個操做是:獲取元素時等待隊列變爲非空,以及存儲元素時等待空間變得可用(阻塞)。
  2. BlockingQueue 方法以四種形式出現,對於不能當即知足但可能在未來某一時刻能夠知足的操做,這四種形式的處理方式不一樣:第一種是拋出一個異常,第二種是返回一個特殊值(null 或 false,具體取決於操做),第三種是在操做能夠成功前,無限期地阻塞當前線程,第四種是在放棄前只在給定的最大時間限制內阻塞。下表中總結了這些方法:
  3. BlockingQueue 不接受 null 元素。試圖 addput 或 offer 一個 null 元素時,某些實現會拋出 NullPointerExceptionnull 被用做指示 poll 操做失敗的警惕值。

  4.  BlockingQueue 能夠是限定容量的。它在任意給定時間均可以有一個 remainingCapacity超出此容量,便沒法無阻塞地 put 附加元素。沒有任何內部容量約束的 BlockingQueue 老是報告 Integer.MAX_VALUE 的剩餘容量。

  5.  BlockingQueue 實現主要用於生產者-使用者隊列BlockingQueue 能夠安全地與多個生產者和多個使用者一塊兒使用。但它另外還支持 Collection 接口。所以,舉例來講,使用 remove(x) 從隊列中移除任意一個元素是有可能的。然而,這種操做一般 會有效執行,只能有計劃地偶爾使用,好比在取消排隊信息時。

  6.  BlockingQueue 實現是線程安全的。全部排隊方法均可以使用內部鎖或其餘形式的併發控制來自動達到它們的目的。然而,大量的 Collection 操做(addAllcontainsAllretainAll 和 removeAll沒有 必要自動執行,除非在實現中特別說明。所以,舉例來講,在只添加了 c 中的一些元素後,addAll(c) 有可能失敗(拋出一個異常)。

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

  8. 內存一致性效果:當存在其餘併發 collection 時,將對象放入 BlockingQueue 以前的線程中的操做 happen-before 隨後經過另外一線程從 BlockingQueue中訪問或移除該元素的操做。

7. ArrayBlockingQueue(JUC)

1. ArrayBlockingQueue 結構圖

2. ArrayBlockingQueue 重要特色

  1. 一個由數組支持的有界阻塞隊列。此隊列按 FIFO(先進先出)原則對元素進行排序。隊列的頭部 是在隊列中存在時間最長的元素。隊列的尾部 是在隊列中存在時間最短的元素。新元素插入到隊列的尾部,隊列獲取操做則是從隊列頭部開始得到元素。

  2. 這是一個典型的「有界緩存區」,固定大小的數組在其中保持生產者插入的元素和使用者提取的元素。一旦建立了這樣的緩存區,就不能再增長其容量。試圖向已滿隊列中放入元素會致使操做受阻塞;試圖從空隊列中提取元素將致使相似阻塞。

  3. 此類支持對等待的生產者線程和使用者線程進行排序的可選公平策略。默認狀況下,不保證是這種排序。然而,經過將公平性 (fairness) 設置爲 true 而構造的隊列容許按照 FIFO 順序訪問線程。公平性一般會下降吞吐量,但也減小了可變性和避免了「不平衡性」。

  4. ArrayBlockingQueue內部有個循環數組items用來存放隊列元素,putIndex下標標示入隊元素下標,takeIndex是出隊下標,count統計隊列元素個數,從定義可知道並無使用volatile修飾,這是由於訪問這些變量使用都是在鎖塊內,並不存在可見性問題。

  5. 有個獨佔鎖lock用來對出入隊操做加鎖,這致使同時只有一個線程能夠訪問入隊出隊,

  6. notEmpty,notFull條件變量用來進行出入隊的同步。另外構造函數必須傳入隊列大小參數,因此爲有界隊列,默認是Lock爲非公平鎖。

  7. offer操做:在隊尾插入元素,若是隊列滿則返回false,否者入隊返回true。因爲在操做共享變量前加了鎖【final ReentrantLock lock = this.lock; 獲取獨佔鎖 lock.lock();】,因此不存在內存不可見問題,加過鎖後獲取的共享變量都是從主內存獲取的,而不是在CPU緩存或者寄存器裏面的值,釋放鎖後修改的共享變量值會刷新會主內存中。另外這個隊列是使用循環數組實現,因此計算下一個元素存放下標時候有些特殊。【i=putIndex;  return(++i == items.length) ? 0 : i;】另外insert後調用 notEmpty.signal();是爲了激活調用notEmpty.await()阻塞後放入notEmpty條件隊列中的線程。

  8. put操做:在隊列尾部添加元素,若是隊列滿則等待隊列有空位置插入後返回。【final ReentrantLock lock = this.lock;  獲取可被中斷鎖  lock.lockInterruptibly();】若是隊列滿了那麼當前線程會阻塞,直到出隊操做調用了notFull.signal方法激活該線程。
  9. size操做:獲取隊列元素個數,很是精確,由於計算size時候加了獨佔鎖,其餘線程不能入隊或者出隊或者刪除元素
  10. ArrayBlockingQueue經過使用全局獨佔鎖實現同時只能有一個線程進行入隊或者出隊操做,這個鎖的粒度比較大,有點相似在方法上添加synchronized的意味。其中offer,poll操做經過簡單的加鎖進行入隊出隊操做,而put,take則使用了條件變量實現若是隊列滿則等待,若是隊列空則等待,而後分別在出隊和入隊操做中發送信號激活等待線程實現同步。另外相比LinkedBlockingQueue,ArrayBlockingQueue的size操做的結果是精確的,由於計算前加了全局鎖。

8. LinkedBlockingQueue(JUC)

1. LinkedBlockingQueue 結構圖

 

 

一個由連接節點支持的可選有界隊列。

2. LinkedBlockingQueue 重要特色

  1. 一個基於已連接節點的、範圍任意的 blocking queue。此隊列按 FIFO(先進先出)排序元素。隊列的頭部 是在隊列中時間最長的元素。隊列的尾部 是在隊列中時間最短的元素。新元素插入到隊列的尾部,而且隊列獲取操做會得到位於隊列頭部的元素。連接隊列的吞吐量一般要高於基於數組的隊列,可是在大多數併發應用程序中,其可預知的性能要低。

  2. 可選的容量範圍構造方法參數做爲防止隊列過分擴展的一種方法。若是未指定容量,則它等於 Integer.MAX_VALUE除非插入節點會使隊列超出容量,不然每次插入後會動態地建立連接節點。

  3. LinkedBlockingQueue中也有兩個Node分別用來存放首尾節點,而且裏面有個初始值爲0的原子變量count用來記錄隊列元素個數,另外裏面有兩個ReentrantLock的獨佔鎖,分別用來控制元素入隊和出隊加鎖,其中takeLock用來控制同時只有一個線程能夠從隊列獲取元素,其餘線程必須等待,putLock控制同時只能有一個線程能夠獲取鎖去添加元素,其餘線程必須等待。另外notEmpty和notFull用來實現入隊和出隊的同步。 另外因爲出入隊是兩個非公平獨佔鎖,因此能夠同時又一個線程入隊和一個線程出隊,其實這個是個生產者-消費者模型。

9. PriorityBlockingQueue(JUC)

1. PriorityBlockingQueue 結構圖

 

一個基於優先級堆的無界優先級阻塞隊列。

2. PriorityBlockingQueue 重要特色

  1. 一個基於優先級堆的無界阻塞隊列。,它使用與類 PriorityQueue 相同的順序規則,而且提供了阻塞獲取操做。雖然此隊列邏輯上是無界的,可是資源被耗盡時試圖執行 add 操做也將失敗(致使 OutOfMemoryError)。
  2. 此類不容許使用 null 元素。依賴天然順序的優先級隊列也不容許插入不可比較的對象(這樣作會致使拋出 ClassCastException)。
  3. 此類及其迭代器能夠實現 Collection 和 Iterator 接口的全部可選 方法。iterator() 方法中提供的迭代器並 保證以特定的順序遍歷 PriorityBlockingQueue 的元素。若是須要有序地進行遍歷,則應考慮使用 Arrays.sort(pq.toArray())。此外,可使用方法 drainTo 按優先級順序移除 所有或部分元素,並將它們放在另外一個 collection 中。
  4. 在此類上進行的操做不保證具備同等優先級的元素的順序。若是須要實施某一排序,那麼能夠定義自定義類或者比較器,比較器可以使用修改鍵斷開主優先級值之間的聯繫。例如,如下是應用先進先出 (first-in-first-out) 規則斷開可比較元素之間聯繫的一個類。要使用該類,則須要插入一個新的 FIFOEntry(anEntry) 來替換普通的條目對象。
  5. PriorityBlockingQueue內部有個數組queue用來存放隊列元素,size用來存放隊列元素個數,allocationSpinLockOffset是用來在擴容隊列時候作cas的,目的是保證只有一個線程能夠進行擴容。
  6. 因爲這是一個優先級隊列因此有個比較器comparator用來比較元素大小。lock獨佔鎖對象用來控制同時只能有一個線程能夠進行入隊出隊操做。notEmpty條件變量用來實現take方法阻塞模式。這裏沒有notFull 條件變量是由於這裏的put操做是非阻塞的,爲啥要設計爲非阻塞的是由於這是無界隊列。
  7. 最後PriorityQueue q用來搞序列化的。以下構造函數,默認隊列容量爲11,默認比較器爲null;

10. DelayQueue(JUC)

1. DelayQueue 結構圖

 

一個使用優先級隊列實現的無界阻塞隊列,只有在延遲期滿時才能從中提取元素。

DelayQueue隊列中每一個元素都有個過時時間,而且隊列是個優先級隊列,當從隊列獲取元素時候,只有過時元素纔會出隊列。

2. DelayQueue 重要特色

  1. Delayed 元素的一個無界阻塞隊列,只有在延遲期滿時才能從中提取元素。該隊列的頭部 是延遲期滿後保存時間最長的 Delayed 元素。若是延遲都尚未期滿,則隊列沒有頭部,而且 poll 將返回 null

  2. 當一個元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一個小於等於 0 的值時,將發生到期。即便沒法使用 take 或 poll 移除未到期的元素,也不會將這些元素做爲正常元素對待。例如,size 方法同時返回到期和未到期元素的計數。

  3. 此隊列不容許使用 null 元素。

  4. DelayQueue中內部使用的是PriorityQueue存放數據,使用ReentrantLock實現線程同步,可知是阻塞隊列。另外隊列裏面的元素要實現Delayed接口,一個是獲取當前剩餘時間的接口,一個是元素比較的接口,由於這個是有優先級的隊列。

11. SychronousQueue(JUC)

1. SychronousQueue 結構圖

一個不存儲元素、沒有內部容量的阻塞同步隊列。

SynchronousQueue的吞吐量高於LinkedBlockingQueue 和 ArrayBlockingQueue。

2. SychronousQueue 重要特色

  1. 一個不存儲元素、沒有內部容量的阻塞隊列,其中每一個插入操做必須等待另外一個線程的對應移除操做 ,反之亦然。同步隊列沒有任何內部容量,甚至連一個隊列的容量都沒有。不能在同步隊列上進行 peek,由於僅在試圖要移除元素時,該元素才存在;除非另外一個線程試圖移除某個元素,不然也不能(使用任何方法)插入元素;也不能迭代隊列,由於其中沒有元素可用於迭代。隊列的 是嘗試添加到隊列中的首個已排隊插入線程的元素;若是沒有這樣的已排隊線程,則沒有可用於移除的元素而且 poll() 將會返回 null。對於其餘 Collection 方法(例如 contains),SynchronousQueue 做爲一個空 collection。

  2. 此隊列不容許 null 元素

  3. 同步隊列相似於 CSP 和 Ada 中使用的 簡單彙集(rendezvous)機制信道。它很是適合於傳遞性設計,在這種設計中,在一個線程中運行的對象要將某些信息、事件或任務傳遞給在另外一個線程中運行的對象,它就必須與該對象同步。 

  4. 對於正在等待的生產者和使用者線程而言,此類支持可選的公平排序策略。默認狀況下不保證這種排序。可是,使用公平設置爲 true 所構造的隊列可保證線程以 FIFO 的順序進行訪問。

  5. SynchronousQueue的吞吐量高於LinkedBlockingQueue 和 ArrayBlockingQueue。

12. LinkedTransferQueue(JUC)

1. LinkedTransferQueue 結構圖

LinkedTransferQueue是一個由鏈表結構組成的無界阻塞TransferQueue隊列。

2. LinkedTransferQueue 重要特色

  1. LinkedTransferQueue是一個由鏈表結構組成的無界阻塞TransferQueue隊列。
  2. 相對於其餘阻塞隊列LinkedTransferQueue多了tryTransfer和transfer方法。
  3. transfer方法。若是當前有消費者正在等待接收元素(消費者使用take()方法或帶時間限制的poll()方法時),transfer方法能夠把生產者傳入的元素馬上transfer(傳輸)給消費者。若是沒有消費者在等待接收元素,transfer方法會將元素存放在隊列的tail節點,並等到該元素被消費者消費了才返回。
  4. tryTransfer方法則是用來試探下生產者傳入的元素是否能直接傳給消費者。若是沒有消費者等待接收元素,則返回false。和transfer方法的區別是tryTransfer方法不管消費者是否接收,方法當即返回。而transfer方法是必須等到消費者消費了才返回。

  5.  對於帶有時間限制的tryTransfer(E e, long timeout, TimeUnit unit)方法,則是試圖把生產者傳入的元素直接傳給消費者,可是若是沒有消費者消費該元素則等待指定的時間再返回,若是超時還沒消費元素,則返回false,若是在超時時間內消費了元素,則返回true。

13. LinkedBlockingDeque(JUC)

1. LinkedBlockingDeque 結構圖

 

 一個基於已連接節點的、任選範圍的阻塞雙端隊列。

2. LinkedBlockingDeque 重要特色

  1. 一個基於已連接節點的、任選範圍的阻塞雙端隊列。
  2. 可選的容量範圍構造方法參數是一種防止過分膨脹的方式。若是未指定容量,那麼容量將等於 Integer.MAX_VALUE只要插入元素不會使雙端隊列超出容量,每次插入後都將動態地建立連接節點。
  3. 大多數操做都以固定時間運行(不計阻塞消耗的時間)。異常包括 removeremoveFirstOccurrenceremoveLastOccurrencecontainsiterator.remove() 以及批量操做,它們均以線性時間運行。

 

摘錄網址

  1. 併發隊列-無界非阻塞隊列 ConcurrentLinkedQueue 原理探究
  2. 併發隊列-有界阻塞隊列ArrayBlockingQueue原理探究
  3. 併發隊列-無界阻塞隊列LinkedBlockingQueue原理探究
  4. 併發隊列-無界阻塞優先級隊列PriorityBlockingQueue原理探究
  5. JUC源碼分析-集合篇(八):SynchronousQueue
相關文章
相關標籤/搜索