天天看點

java隊列Queue及阻塞隊列

java隊列

接口Queue類在java.util包,定義了以下6個方法

java隊列Queue及阻塞隊列

詳細檢視官方文檔​​https://docs.oracle.com/javase/7/docs/api/java/util/Queue.html​​

什麼是阻塞隊列 BlockingQueue

  隊列是一種資料結構,它的特點是先進先出(First In First Out),它有兩個基本操作:在隊列尾部加入一個元素,從隊列頭部移除一個元素。隊列在多線程應用中,常用于生産-消費場景。

  BlockingQueue 是 Java util.concurrent 包下重要的資料結構,BlockingQueue 提供了線程安全的隊列通路方式:當阻塞隊列進行插入資料時,如果隊列已滿,線程将會阻塞等待直到隊列非滿;從阻塞隊列取資料時,如果隊列已空,線程将會阻塞等待直到隊列非空。并發包下很多進階同步類的實作都是基于 BlockingQueue 實作的。

  BlockingQueue 具有 4 組不同的方法用于插入、移除以及對隊列中的元素進行檢查。如果請求的操作不能得到立即執行的話,每個方法的表現也不同。這些方法如下:

java隊列Queue及阻塞隊列

  按照上圖,我們可以知道jdk1.5中的阻塞隊列的操作:

  add        增加一個元索                     如果隊列已滿,則抛出一個IIIegaISlabEepeplian異常

  remove   移除并傳回隊列頭部的元素    如果隊列為空,則抛出一個NoSuchElementException異常

  element  傳回隊列頭部的元素             如果隊列為空,則抛出一個NoSuchElementException異常

  offer       添加一個元素并傳回true       如果隊列已滿,則傳回false

  poll         移除并返問隊列頭部的元素    如果隊列為空,則傳回null

  peek       傳回隊列頭部的元素             如果隊列為空,則傳回null

  put         添加一個元素                      如果隊列滿,則阻塞

  take        移除并傳回隊列頭部的元素     如果隊列為空,則阻塞

BlockingQueue 是個接口,你需要使用它的實作之一來使用 BlockingQueue,Java.util.concurrent 包下具有以下 BlockingQueue 接口的實作類:

ArrayBlockingQueue :一個由數組支援的有界隊列。

LinkedBlockingQueue :一個由連結節點支援的可選有界隊列。

PriorityBlockingQueue :一個由優先級堆支援的無界優先級隊列。

DelayQueue :一個由優先級堆支援的、基于時間的排程隊列。

SynchronousQueue :一個利用 BlockingQueue 接口的簡單聚集(rendezvous)機制。

  ArrayBlockingQueue:ArrayBlockingQueue 是一個有界的阻塞隊列,其内部實作是将對象放到一個數組裡。有界也就意味着,它不能夠存儲無限多數量的元素。它有一個同一時間能夠存儲元素數量的上限。你可以在對其初始化的時候設定這個上限,但之後就無法對這個上限進行修改了。

  DelayQueue:DelayQueue 對元素進行持有直到一個特定的延遲到期。注入其中的元素必須實作 java.util.concurrent.Delayed 接口。

  LinkedBlockingQueue:LinkedBlockingQueue 内部以一個鍊式結構對其元素進行存儲。如果需要的話,這一鍊式結構可以選擇一個上限。如果沒有定義上限,将使用 Integer.MAX_VALUE 作為上限。

  PriorityBlockingQueue:PriorityBlockingQueue 是一個無界的并發隊列。它使用了和類 java.util.PriorityQueue 一樣的排序規則。你無法向這個隊列中插入 null 值。所有插入到 PriorityBlockingQueue 的元素必須實作 java.lang.Comparable 接口。是以該隊列中元素的排序就取決于你自己的 Comparable 實作。

  SynchronousQueue:SynchronousQueue 是一個特殊的隊列,它的内部同時隻能夠容納單個元素。如果該隊列已有一進制素的話,試圖向隊列中插入一個新元素的線程将會阻塞,直到另一個線程将該元素從隊列中抽走。同樣,如果該隊列為空,試圖向隊列中抽取一個元素的線程将會阻塞,直到另一個線程向隊列中插入了一條新的元素。據此,把這個類稱作一個隊列顯然是誇大其詞了。它更多像是一個彙合點。