java中的阻塞隊列BlockingQueue,隊列blockingqueue

來源:互聯網
上載者:User

java中的阻塞隊列BlockingQueue,隊列blockingqueue

一、概述

位於java.util.concurrent下,聲明:public interfaceBlockingQueue<E> extendsQueue<E>

支援兩個附加操作的 Queue,這兩個操作是:擷取元素時等待隊列變為非空,以及儲存元素時等待空間變得可用。

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

  拋出異常 特殊值 阻塞 逾時
插入 add(e) offer(e) put(e) offer(e, time, unit)
移除 remove() poll() take() poll(time, unit)
檢查 element() peek() 不可用 不可用
BlockingQueue 不接受 null 元素。試圖 add、put 或 offer 一個null 元素時,某些實現會拋出 NullPointerException。null 被用作指示 poll 操作失敗的警戒值。

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

BlockingQueue 實現主要用於生產者-使用者隊列,但它另外還支援Collection 介面。因此,舉例來說,使用remove(x) 從隊列中移除任意一個元素是有可能的。然而,這種操作通常 會有效執行,只能有計劃地偶爾使用,比如在清除佇列資訊時。

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

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

以下是基於典型的生產者-使用者情境的一個用例。注意,BlockingQueue 可以安全地與多個生產者和多個使用者一起使用。 

class Producer implements Runnable {   private final BlockingQueue queue;   Producer(BlockingQueue q) { queue = q; }   public void run() {     try {       while(true) { queue.put(produce()); }     } catch (InterruptedException ex) { ... handle ...}   }   Object produce() { ... } } class Consumer implements Runnable {   private final BlockingQueue queue;   Consumer(BlockingQueue q) { queue = q; }   public void run() {     try {       while(true) { consume(queue.take()); }     } catch (InterruptedException ex) { ... handle ...}   }   void consume(Object x) { ... } } class Setup {   void main() {     BlockingQueue q = new SomeQueueImplementation();     Producer p = new Producer(q);     Consumer c1 = new Consumer(q);     Consumer c2 = new Consumer(q);     new Thread(p).start();     new Thread(c1).start();     new Thread(c2).start();   } }

記憶體一致性效果:當存在其他並發 collection 時,將對象放入 BlockingQueue 之前的線程中的操作 happen-before 隨後通過另一線程從 BlockingQueue 中訪問或移除該元素的操作。

此介面是 Java Collections Framework 的成員。

二、方法

1、booleanadd(E e)  

將指定元素插入此隊列中(如果立即可行且不會違反容量限制),成功時返回 true,如果當前沒有可用的空間,則拋出 IllegalStateException。當使用有容量限制的隊列時,通常首選 offer

指定者:
介面 Collection<E> 中的 add
指定者:
介面 Queue<E> 中的 add
參數:
e - 要添加的元素
返回:
true(根據 Collection.add(E) 的規定)
拋出:
IllegalStateException - 如果由於容量限制此時不能添加該元素
ClassCastException - 如果指定元素的類不允許將其添加到此隊列
NullPointerException - 如果指定元素為 null
IllegalArgumentException - 如果指定元素的某些屬性不允許將其添加到此隊列
2、boolean offer(E e)  
將指定元素插入此隊列中(如果立即可行且不會違反容量限制),成功時返回 true,如果當前沒有可用的空間,則返回 false。當使用有容量限制的隊列時,此方法通常要優於 add(E),後者可能無法插入元素,而只是拋出一個異常。

指定者:
介面 Queue<E> 中的 offer
參數:
e - 要添加的元素
返回:
如果該元素已添加到此隊列,則返回 true;否則返回 false
拋出:
ClassCastException - 如果指定元素的類不允許將其添加到此隊列
NullPointerException - 如果指定元素為 null
IllegalArgumentException - 如果指定元素的某些屬性不允許將其添加到此隊列
3、void put(E e) throwsInterruptedException  將指定元素插入此隊列中,將等待可用的空間(如果有必要)。

參數:
e - 要添加的元素
拋出:
InterruptedException - 如果在等待時被中斷
ClassCastException - 如果指定元素的類不允許將其添加到此隊列
NullPointerException - 如果指定元素為 null
IllegalArgumentException - 如果指定元素的某些屬性不允許將其添加到此隊列

4、boolean offer(E e, long timeout, TimeUnit unit)  throwsInterruptedException

將指定元素插入此隊列中,在到達指定的等待時間前等待可用的空間(如果有必要)。

參數:
e - 要添加的元素
timeout - 放棄之前等待的時間長度,以 unit 為時間單位
unit - 確定如何解釋 timeout 參數的 TimeUnit
返回:
如果成功,則返回 true;如果在空間可用前超過了指定的等待時間,則返回 false
拋出:
InterruptedException - 如果在等待時被中斷
ClassCastException - 如果指定元素的類不允許將其添加到此隊列
NullPointerException - 如果指定元素為 null
IllegalArgumentException - 如果指定元素的某些屬性不允許將其添加到此隊列
5、E take() throwsInterruptedException  擷取並移除此隊列的頭部,在元素變得可用之前一直等待(如果有必要)。

返回:
此隊列的頭部
拋出:
InterruptedException - 如果在等待時被中斷
6、E poll(long timeout, TimeUnit unit) throwsInterruptedException

擷取並移除此隊列的頭部,在指定的等待時間前等待可用的元素(如果有必要)。

參數:
timeout - 放棄之前要等待的時間長度,用 unit 的時間單位表示
unit - 確定如何解釋 timeout 參數的 TimeUnit
返回:
此隊列的頭部;如果在元素可用前超過了指定的等待時間,則返回 null
拋出:
InterruptedException - 如果在等待時被中斷
7、int remainingCapacity()  

返回在無阻塞的理想情況下(不存在記憶體或資源約束)此隊列能接受的附加元素數量;如果沒有內部限制,則返回 Integer.MAX_VALUE。

注意,不能 總是通過檢查 remainingCapacity 來判斷嘗試插入元素是否成功,因為可能出現這樣的情況:其他線程即將插入或移除一個元素。

返回:
剩餘容量
8、boolean remove(Object o)  
從此隊列中移除指定元素的單個執行個體(如果存在)。更確切地講,如果此隊列包含一個或多個滿足 o.equals(e) 的元素 e,則移除該元素。如果此隊列包含指定元素(或者此隊列由於調用而發生更改),則返回true。

指定者:
介面 Collection<E> 中的 remove
參數:
o - 要從此隊列移除的元素(如果存在)
返回:
如果此隊列由於調用而發生更改,則返回 true
拋出:
ClassCastException - 如果指定元素的類與此隊列不相容(可選)
NullPointerException - 如果指定元素為 null(可選)
9、boolean contains(Object o)  
如果此隊列包含指定元素,則返回 true。更確切地講,若且唯若此隊列至少包含一個滿足 o.equals(e) 的元素 e時,返回 true。

指定者:
介面 Collection<E> 中的 contains
參數:
o - 檢查是否包含在此隊列中的對象
返回:
如果此隊列包含指定元素,則返回 true
拋出:
ClassCastException - 如果指定元素的類與此隊列不相容(可選)
NullPointerException - 如果指定元素為 null(可選)
10、int drainTo(Collection<? superE> c)  
移除此隊列中所有可用的元素,並將它們添加到給定 collection 中。此操作可能比反覆輪詢此隊列更有效。在試圖向 collection c 中添加元素沒有成功時,可能導致在拋出相關異常時,元素會同時在兩個 collection 中出現,或者在其中一個 collection 中出現,也可能在兩個 collection 中都不出現。如果試圖將一個隊列放入自身隊列中,則會導致IllegalArgumentException 異常。此外,如果進行中此操作時修改指定的 collection,則此操作行為是不確定的。

參數:
c - 接收傳輸元素的 collection
返回:
傳輸元素的數量
拋出:
UnsupportedOperationException - 如果指定 collection 不支援添加元素
ClassCastException - 如果此隊列元素的類不允許將其添加到指定 collection
NullPointerException - 如果指定 collection 為 null
IllegalArgumentException - 如果指定 collection 是此隊列,或者此隊列元素的某些屬性不允許將其添加到指定 collection
11、int drainTo(Collection<? superE> c, int maxElements)  
最多從此隊列中移除給定數量的可用元素,並將這些元素添加到給定 collection 中。在試圖向 collection c 中添加元素沒有成功時,可能導致在拋出相關異常時,元素會同時在兩個 collection 中出現,或者在其中一個 collection 中出現,也可能在兩個 collection 中都不出現。如果試圖將一個隊列放入自身隊列中,則會導致IllegalArgumentException 異常。此外,如果進行中此操作時修改指定的 collection,則此操作行為是不確定的。

參數:
c - 接收傳輸元素的 collection
maxElements - 傳輸元素的最大數量
返回:
傳輸元素的數量
拋出:
UnsupportedOperationException - 如果指定 collection 不支援添加元素
ClassCastException - 如果此隊列元素的類不允許將其添加到指定 collection
NullPointerException - 如果指定 collection 為 null
IllegalArgumentException - 如果指定 collection 是此隊列,或者此隊列元素的某些屬性不允許將其添加到指定 collection








聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.