java併發程式設計工具類JUC第七篇:BlockingDeque雙端阻塞佇列

字母哥部落格發表於2021-06-09

在之前的文章中已經為大家介紹了java併發程式設計的工具:BlockingQueue介面、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue,本文為系列文章第七篇。

BlockingDeque介面和BlockingQueue介面一樣都是在java.util.concurrent中定義的,它代表了一個執行緒安全的“雙端佇列”,以執行緒安全的方式向佇列中新增元素或獲取元素。本篇文章將帶大家進一步瞭解BlockingDeque

deque是 "Double Ended Queue "的縮寫。因此“雙端佇列”的含義就是可以從兩端(隊首或隊尾)插入和取出元素的佇列。

如果某個執行緒既生產又消費同一個佇列的元素,那麼就可以使用BlockingDeque雙端佇列。如果生產執行緒需要在佇列的兩端插入,而消費執行緒需要從佇列的兩端刪除,也可以只使用BlockingDeque雙端佇列。參考下面的圖進行理解

一個執行緒生產元素並將它們插入到佇列兩端中的任何一端。如果BlockingDeque當前是滿的,插入執行緒將被阻塞,直到移除執行緒從BlockingDeque中取出一個元素。如果BlockingDeque當前為空,那麼移除執行緒將被阻塞,直到插入執行緒將一個元素插入到BlockingDeque中。

BlockingDeque 方法

BlockingDeque有4組不同的方法,用於插入、刪除和檢查deque中的元素。每組方法在所要求的操作不能被立即執行的情況下表現也有所不同。參考下面的表格

隊首操作 丟擲異常 返回特定值 阻塞後一直等待 阻塞後等待超時
插入物件 addFirst(o) offerFirst(o) putFirst(o) offerFirst(o, timeout, timeunit)
移除物件 removeFirst(o) pollFirst() takeFirst() pollFirst(timeout, timeunit)
檢查物件存在 getFirst() peekFirst()
隊尾操作 丟擲異常 返回特定值 阻塞後一直等待 阻塞後等待超時
插入物件 addLast(o) offerLast(o) putLast(o) offerLast(o, timeout, timeunit)
移除物件 removeLast(o) pollLast() takeLast() pollLast(timeout, timeunit)
檢查物件存在 getLast() peekLast()

大家可以看到,這些方法和和BlockingQueue的方法有些相似,只是在方法的基礎上加了xxxFirst和xxxLast,所以可以參考我之前的文章對比學習),上面的方法的四種行為分別的含義是

  1. 丟擲異常: 如果呼叫方法後不能立即響應結果(空佇列或滿佇列),則丟擲異常。
  2. 返回特定值: 如果呼叫方法後不能立即響應結果(空佇列或滿佇列),則返回特定的值(通常是true/false),true表示方法執行成功,否則表示方法執行失敗。
  3. 阻塞後一直等待: 如果呼叫方法後不能立即響應結果(空佇列或滿佇列),該方法將被阻塞一直處於等待狀態。
  4. 阻塞後等待超時: 如果呼叫方法後不能立即響應結果(空佇列或滿佇列),該方法將在一定時間範圍內被阻塞等待,也就是在超時時間範圍內阻塞。當超出超時時間之後,方法執行緒將不再阻塞,而是返回一個特定的值(通常是true/false),true表示方法執行成功,否則表示方法執行失敗。

BlockingDeque繼承BlockingQueue

BlockingDeque介面繼承了BlockingQueue介面。這意味著你可以將BlockingDeque作為一個BlockingQueue使用。如果你這樣做,各種插入方法將把元素新增到deque的末尾,而移除方法將從deque的隊首移除元素。BlockingQueue介面的插入和刪除方法,就是這樣做的。

下面是BlockingQueue的方法在BlockingDeque實現中的作用對照表

BlockingQueue BlockingDeque
add() addLast()
offer() offerLast()
put() putLast()
remove() removeFirst()
poll pollFirst()
take() takeFirst()
element() getFirst()
peek() peekFirst()

BlockingDeque 介面實現類

BlockingDeque是一個介面,所以當我們真正對它進行例項化的時候,需要使用它的介面實現類。在java.util.concurrent包中的LinkedBlockingDeque方法實現了BlockingDeque介面。

其使用方法也與BlockingQueue 大同小異,所以此處只做簡單的介紹。

//初始化一個LinkedBlockingDeque
BlockingDeque<String> deque = new LinkedBlockingDeque<String>();

deque.addFirst("1");//向隊首新增元素
deque.addLast("2"); //向隊尾新增元素

String two = deque.takeLast(); //從隊尾獲取元素
String one = deque.takeFirst(); //從隊首獲取元素

歡迎關注我的部落格,裡面有很多精品合集

  • 本文轉載註明出處(必須帶連線,不能只轉文字):字母哥部落格

覺得對您有幫助的話,幫我點贊、分享!您的支援是我不竭的創作動力! 。另外,筆者最近一段時間輸出瞭如下的精品內容,期待您的關注。

相關文章