併發程式設計 阻塞佇列BlockingQueue

2021-10-05 03:24:16 字數 2997 閱讀 2112

在佇列中插入乙個佇列元素稱為入隊,從佇列中刪除乙個佇列元素稱為出隊。因為佇列只允許在一端插入,在另一端刪除,所以只有最早進入佇列的元素才能最先從佇列中刪除,故佇列又稱為先進先出(fifo—first in first out)線性表。

1)支援阻塞的插入方法:意思是當佇列滿時,佇列會阻塞插入元素的執行緒,直到佇列不滿。

2)支援阻塞的移除方法:意思是在隊列為空時,獲取元素的執行緒會等待佇列變為非空。

arrayblockingqueue:乙個由陣列結構組成的有界阻塞佇列。

linkedblockingqueue:乙個由鍊錶結構組成的有界阻塞佇列。

priorityblockingqueue:乙個支援優先順序排序的無界阻塞佇列。

delayqueue:乙個使用優先順序佇列實現的無界阻塞佇列。

synchronousqueue:乙個不儲存元素的阻塞佇列。

linkedtransferqueue:乙個由鍊錶結構組成的無界阻塞佇列。

linkedblockingdeque:乙個由鍊錶結構組成的雙向阻塞佇列。

有限佇列就是長度有限,滿了以後生產者會阻塞,無界佇列就是裡面能放無數的東西而不會因為佇列長度限制被阻塞,當然空間限制**於系統資源的限制,如果處理不及時,導致佇列越來越大越來越大,超出一定的限制致使記憶體超限,作業系統或者jvm 幫你解決煩惱,直接把你oom kill 省事了。

arrayblockingqueue

是乙個用陣列實現的有界阻塞佇列。此佇列按照先進先出(fifo)的原則對元素進行排序。預設情況下不保證執行緒公平的訪問佇列,所謂公平訪問佇列是指阻塞的執行緒,可以按照阻塞的先後順序訪問佇列,即先阻塞執行緒先訪問佇列。非公平性是對先等待的執行緒是非公平的,當佇列可用時,阻塞的執行緒都可以爭奪訪問佇列的資格,有可能先阻塞的執行緒最後才訪問佇列。初始化時有引數可以設定

linkedblockingqueue

是乙個用鍊錶實現的有界阻塞佇列。此佇列的預設和最大長度為integer.max_value。此佇列按照先進先出的原則對元素進行排序。

佇列中鎖的實現不同

arrayblockingqueue 實現的佇列中的鎖是沒有分離的,即生產和消費用的是同乙個鎖;

linkedblockingqueue 實現的佇列中的鎖是分離的,即生產用的是putlock,消費是takelock

在生產或消費時操作不同

arrayblockingqueue 實現的佇列中在生產和消費的時候,是直接將列舉物件插入或移除的;

linkedblockingqueue 實現的佇列中在生產和消費的時候,需要把列舉物件轉換為node進行插入或移除,會影響效能

佇列大小初始化方式不同

arrayblockingqueue 實現的佇列中必須指定佇列的大小;

linkedblockingqueue 實現的佇列中可以不指定佇列的大小,但是預設是integer.max_value

delayqueue

是乙個支援延時獲取元素的無界阻塞佇列。

delayqueue 非常有用,可以將delayqueue 運用在以下應用場景。

快取系統的設計:可以用delayqueue 儲存快取元素的有效期,使用乙個線

程迴圈查詢delayqueue,一旦能從delayqueue 中獲取元素時,表示快取有效期

到了。還有訂單到期,限時支付等等

使用了等待通知模式實現。所謂通知模式,就是當生產者往滿的佇列裡新增元素時會阻塞住生產者,當消費者消費了乙個佇列中的元素後,會通知生產者當前佇列可用

定義物件包裝類

public

class

itemvo

implements

delayed

public

long

getactivetime()

public t getdata()

/* * 這個方法返回到啟用日期的剩餘時間,時間單位由單位引數指定。

*/public

long

getdelay

(timeunit unit)

/* *delayed介面繼承了comparable介面,按剩餘時間排序,實際計算考慮精度為納秒數

*/public

intcompareto

(delayed o)

else

else}}

}

定義訂單實體

public

class

order

public string gettano()

}

業務**中定義生產者,45分鐘訂單超時取消

/** 放入延時佇列 超過45分鐘訂單自動取消*/

order ordertb =

neworder

(tano)

;itemvo

itemtb =

newitemvo

(45*60

,ordertb)

;fetchorder.queue.

offer

(itemtb)

;

@component

public

class

fetchorder

implements

catch

(interruptedexception e)}}

}

當然存在缺點:單機、不能持久化、宕機任務丟失等。

還有其他方案:

最簡單的方式,定時掃表

使用rabbitmq 實現 rabbitmq實現延遲佇列

基於redis自研延遲佇列

併發程式設計 優先順序阻塞佇列

優先順序阻塞佇列 priorityblockingqueue。public static void main string args throws interruptedexceptiontask的比較方式為 override public int compareto task task 執行效果截...

Java併發程式設計之阻塞佇列與Fork Join框架

阻塞佇列是支援兩個附加操作的佇列。這兩個附加操作支援阻塞插入和移除方法 阻塞佇列通常用於生產者 消費者場景。生產者是向佇列新增元素的執行緒,使用者是將元素從佇列中取出的執行緒,阻塞佇列是儲存和檢索元素的容器。阻塞佇列的4種處理方式 丟擲異常 返回特殊值 一直阻塞 超時退出 arrayblocking...

併發程式設計 join 阻塞

看看join 阻塞 很多時候,乙個執行緒的輸入可能非常依賴於另外乙個或者多個執行緒的輸出,此時,這個執行緒就需要等待依賴的執行緒執行完畢,才能繼續執行。jdk提供了join 操作來實現這個功能 a依賴b,那麼在a執行緒中去呼叫 b.join a執行緒開始等待b執行緒 無限等待,直到目標執行緒執行完畢...