阻塞佇列BlockingQueue

2021-09-01 15:29:43 字數 3684 閱讀 4587

1、佇列queue介紹

queue是jdk1.5引入的介面,繼承collection介面,是collection框架的新成員,是種先進先出(fifo)的佇列。

public inte***ce queueextends collection
除了基本的collection操作外,佇列還提供其他的插入、提取和檢查操作。每個方法都存在兩種形式:一種丟擲異常(操作失敗時),另一種返回乙個特殊值(null 或 false,具體取決於操作)。

丟擲異常

返回特殊值

插入add(e)offer(e)

移除remove()poll()

檢查element()peek()

booleanadd(e e)

將指定的元素插入此佇列(如果立即可行且不會違反容量限制),在成功時返回 true,如果當前沒有可用的空間,則丟擲 illegalstateexception。

eelement()

獲取,但是不移除此佇列的頭。

booleanoffer(e e)

將指定的元素插入此佇列(如果立即可行且不會違反容量限制),當使用有容量限制的佇列時,此方法通常要優於add(e),後者可能無法插入元素,而只是丟擲乙個異常。

epeek()

獲取但不移除此佇列的頭;如果此隊列為空,則返回 null。

epoll()

獲取並移除此佇列的頭,如果此隊列為空,則返回 null。

eremove()

獲取並移除此佇列的頭。

佇列通常以 fifo的方式排序各個元素。不過優先順序佇列和 lifo 佇列和堆疊例外,優先順序佇列根據提供的比較器或元素的自然順序對元素進行排序,堆疊按 lifo(後進先出)的方式對元素進行排序。無論使用哪種排序方式,佇列的

頭 都是呼叫remove()poll()所移除的元素。

offer方法可插入乙個元素,否則返回 false。這與collection.add方法不同,該方法只能通過丟擲未經檢查的異常使新增元素失敗。offer 方法設計用於正常的失敗情況,而不是出現異常的情況,例如在容量固定(有界)的佇列中。

remove()poll()方法可移除和返回佇列的頭。到底從佇列中移除哪個元素是佇列排序策略的功能,而該策略在各種實現中是不同的。remove() 和 poll() 方法僅在隊列為空時其行為有所不同:remove() 方法丟擲乙個異常,而 poll() 方法則返回 null。

element()peek()返回,但不移除,佇列的頭。

queue 實現通常不允許插入 null 元素,儘管某些實現(如linkedlist)並不禁止插入 null。即使在允許 null 的實現中,也不應該將 null 插入到 queue 中,因為 null 也用作 poll 方法的乙個特殊返回值,表明佇列不包含元素。

2、阻塞佇列blockingqueue

blockingqueue在concurrent包下,較queue 新增了兩個可阻塞方法put()和take()。

queue 介面並未定義

阻塞佇列的方法,而這在併發程式設計中是很常見的。blockingqueue介面定義了那些等待元素出現或等待佇列中有可用空間的方法,這些方法擴充套件了此介面。

blockingqueue 方法以四種形式出現,對於不能立即滿足但可能在將來某一時刻可以滿足的操作,這四種形式的處理方式不同:第一種是丟擲乙個異常,第二種是返回乙個特殊值(null 或 false,具體取決於操作),第三種是在操作可以成功前,無限期地阻塞當前執行緒,第四種是在放棄前只在給定的最大時間限制內阻塞。下表中總結了這些方法:

丟擲異常

特殊值阻塞

超時插入add(e)offer(e)put(e)offer(e, time, unit)

移除remove()poll()take()poll(time, unit)

檢查element()peek()不可用

不可用

voidput(e e)

將指定元素插入此佇列中,將等待可用的空間(如果有必要)。

etake()

獲取並移除此佇列的頭部,在元素變得可用之前一直等待(如果有必要)

blockingqueue 可以是限定容量的。它在任意給定時間都可以有乙個

remainingcapacity,超出此容量,便無法無阻塞地

put 附加元素。沒有任何內部容量約束的

blockingqueue 總是報告

integer.max_value 的剩餘容量。

blockingqueue 實現是執行緒安全的。所有排隊方法都可以使用內部鎖或其他形式的併發控制來自動達到它們的目的。然而,

大量的 collection 操作(

addall、

containsall、

retainall 和

removeall)

沒有 必要自動執行,除非在實現中特別說明。因此,舉例來說,在只新增了

c 中的一些元素後,

addall(c) 有可能失敗(丟擲乙個異常)。

以下是基於典型的生產者-使用者場景的乙個用例。注意,

blockingqueue 可以安全地與多個生產者和多個使用者一起使用:

class producer implements runnable 

public void run()

} catch (interruptedexception ex)

}object produce()

} class consumer implements runnable

public void run()

} catch (interruptedexception ex)

}void consume(object x)

} class setup

}

併發工具包 阻塞佇列BlockingQueue

阻塞佇列,顧名思義 如果佇列滿了,那麼會進入阻塞狀態,當有消費者從佇列中取出資料後,再解除阻塞狀態。如果隊列為空,從佇列中取資料就會進入阻塞狀態。直至佇列中有資料為止。blockingqueue是介面,目前已知的實現類如下 arrayblockingqueue 底層底層通過陣列來儲存佇列中的元素,所...

等待佇列 阻塞非阻塞

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

阻塞佇列BlockingQueue

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