10 阻塞佇列

2022-10-08 20:42:12 字數 2672 閱讀 6371

阻塞佇列是共享佇列(多執行緒操作),一端輸入,一端輸出

不能無限放佇列,滿了之後就會進入阻塞,取出也同理

當佇列是空的,從佇列中獲取元素的操作將會被阻塞

當佇列是滿的,從佇列中新增元素的操作將會被阻塞

試圖從空的佇列中獲取元素的執行緒將會被阻塞,直到其他執行緒往空的佇列插入新的元素

試圖向已滿的佇列中新增新元素的執行緒將會被阻塞,直到其他執行緒從佇列中移除乙個或多個元素或者完全清空,使佇列變得空閒起來並後續新增

1.arrayblockingqueue

基於陣列的阻塞佇列

由陣列結構組成的有界阻塞佇列

-arrayblockingqueue 在生產者放入資料和消費者獲取資料,都是共用同乙個鎖物件,無法並行

2. linkedblockingqueue

基於鍊錶的阻塞佇列

由鍊錶結構組成的有界(但大小預設值為integer.max_value)阻塞佇列

之所以能夠高效的處理併發資料,還因為其對於生產者端和消費者端分別採用了獨立的鎖來控制資料同步,這也意味著在高併發的情況下生產者和消費者可以並行地操作佇列中的資料,以此來提高整個佇列的併發效能

3.delayqueue

使用優先順序佇列實現的延遲無界阻塞佇列

delayqueue 中的元素只有當其指定的延遲時間到了,才能夠從佇列中獲取到該元素。delayqueue 是乙個沒有大小限制的佇列,因此往佇列中插入資料的操作(生產者)永遠不會被阻塞,而只有獲取資料的操作(消費者)才會被阻塞

4.priorityblockingqueue

基於優先順序的阻塞佇列

支援優先順序排序的無界阻塞佇列

不會阻塞資料生產者,而只會在沒有可消費的資料時,阻塞資料的消費者

5.synchronousqueue

一種無緩衝的等待佇列

相對於有緩衝的 blockingqueue 來說,少了乙個中間經銷商的環節(緩衝區)

不儲存元素的阻塞佇列,也即單個元素的佇列

宣告乙個 synchronousqueue 有兩種不同的方式,它們之間有著不太一樣的行為。

公平模式和非公平模式的區別:

• 公平模式:synchronousqueue 會採用公平鎖,並配合乙個 fifo 佇列來阻塞

多餘的生產者和消費者,從而體系整體的公平策略;

• 非公平模式(synchronousqueue 預設):synchronousqueue 採用非公平鎖,同時配合乙個 lifo 佇列來管理多餘的生產者和消費者

而後一種模式,如果生產者和消費者的處理速度有差距,則很容易出現飢渴的情況,即可能有某些生產者或者是消費者的資料永遠都得不到處理

6.linkedtransferqueue

由鍊錶結構組成的無界阻塞 transferqueue 佇列

由鍊錶組成的無界阻塞佇列

預佔模式。意思就是消費者執行緒取元素時,如果佇列不為空,則直接取走資料,若隊列為空,生成乙個節點(節點元素為 null)入隊,消費者執行緒被等待在這個節點上,生產者執行緒入隊時發現有乙個元素為 null 的節點,生產者執行緒就不入隊了,直接就將元素填充到該節點,並喚醒該節點等待的執行緒,被喚醒的消費者執行緒取走元素,從呼叫的方法返回

7.linkedblockingdeque

由鍊錶結構組成的雙向阻塞佇列

阻塞有兩種情況

插入元素時: 如果當前佇列已滿將會進入阻塞狀態,一直等到佇列有空的位置時再該元素插入,該操作可以通過設定超時引數,超時後返回 false 表示操作失敗,也可以不設定超時引數一直阻塞,中斷後丟擲 interruptedexception異常

讀取元素時: 如果當前隊列為空會阻塞住直到佇列不為空然後返回元素,同樣可以通過設定超時引數

第一種方法:

建立阻塞佇列 blockingqueueblockingqueue = new arrayblockingqueue<>(3);

加入元素system.out.println(blockingqueue.add("a"));,成功為true,失敗為false

檢查元素system.out.println(blockingqueue.element());

取出元素system.out.println(blockingqueue.remove());,先進先出

第二種方法:

加入元素system.out.println(blockingqueue.offer("a"));

取出元素system.out.println(blockingqueue.poll());

第三種方法:

加入元素blockingqueue.put("a");

取出元素system.out.println(blockingqueue.take());

該方法加入元素或者取出元素,如果滿了或者空了,還進行下一步加入或者取出操作,會出現阻塞的狀態,而第一二種方法是直接丟擲異常

第四種方法:

加入元素system.out.println(blockingqueue.offer("a"));

該方法滿了或者空了在進行會有阻塞,但可以加入引數,超時退出system.out.println(blockingqueue.offer("w",3l, timeunit.seconds));

等待佇列 阻塞非阻塞

阻塞 裝置驅動不阻塞,使用者想獲取裝置資源只能不停的查詢,這無謂的消耗cpu資源。而阻塞訪問,不能獲取資源的程序將進入休眠,它將cpu資源 禮讓 給其他程序 喚醒程序的地方最大可能發生在中斷裡面,因為硬體資源獲得的同時往往伴隨著乙個中斷 定義頭 wait queue head t queue 初始化...

阻塞佇列BlockingQueue

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

12 阻塞佇列

非阻塞佇列 priorityqueue linkedlist linkedlist 是雙向鍊錶,它實現了 dequeue 介面 阻塞佇列 1 arrayblockingqueue 基於陣列實現的乙個阻塞佇列,在建立arrayblockingqueue 物件時必須制定容量大小。並且可以指定公平性與非公...