java隊列--queue詳細分析


---恢復內容開始---

Queue:基本上一個隊列就是一個先入先出(FIFO)的數據結構

Queue接口與List、Set同一級別,都是繼承了Collection接口,LinkedList實現了List與Deque接口。

 

Queue實現

 

1、沒有實現阻塞接口的LinkedList:實現了java.util.Queue接口和java.util.AbstractQueue接口

  內置的不阻塞隊列:PriorityQueue和ConcurrentLinkedQueue

  PriorityQueue和ConcurrentLinkedQueue類在Collection FrameWork中加入兩個具體集合實現。

  PriorityQueue類實質上維護了一個有序列表。加入到Queue中的元素根據他們天然排序(通過其java.util.Comparable實現)或者根據傳遞給構造函數的java.util.Comparator來實現定位。

  ConcurrentLinkedQueue是基於鏈接節點的、線程安全的隊列。並發訪問不需要同步。因為它在隊列的尾部添加元素並從頭部刪除它們,所以只要不需要知道隊列的大小,ConcurrentLinkedQueue對公共集合的共享訪問就可以工作得很好。收集關於隊列大小的信息會很慢,需要遍歷隊列。(通過CAS保證並發)

 

2、實現阻塞接口的:

  java.util.concurrent中加入了BlockingQueue接口和五個阻塞隊列類。它實質上就是一種帶有一點扭曲的FIFO數據結構。不是立即從隊列中添加或者刪除元素,線程執行操作阻塞,知道有空間或者元素可用。

  五個隊列所提供的各有不同:

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

    *LinkedBlockingQueue:一個由鏈接節點支持的可選有界隊列。

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

    *DelayQueue:一個由優先級堆支持的、基於時間的調度隊列。

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

下表顯示了jdk1.5中的阻塞隊列的操作:

  add    添加一個元素        如果隊列已滿,拋出一個IllegalStateException(“Queue full”)異常

  remove   移除並返回隊列頭部的元素  如果隊列為空,則拋出一個NoSuchElementException異常

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

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

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

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

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

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

 

 remove、element、offer、poll、peek其實是屬於Queue接口。

 

阻塞隊列的操作可以根據它們的響應方式分為以下三類:add、remove和element,這些操作在你試圖向一個已滿的隊列添加元素或空隊列獲取元素時拋出異常。當然,在多線程程序中,隊列在任何時間都可能變成滿的或空的,所以你可能想使用offer、poll、peek方法。這些方法在無法完成任務時,只是給出一個出錯而不會拋出異常。

 

注意:poll和peek方法出錯會返回null。因此向隊列中插入null值是不合法的

阻塞隊列put和take。put方法在隊列滿時阻塞,take方法在隊列空時阻塞。

 

LinkedBlockingQueue的容量是沒有上限的(在不指定容量時,默認容量為Integer.MAX_VALUE),也可以指定最大容量,它是基於鏈表的隊列,此隊列按FIFO(先進先出)排序元素。(可以實現生產者消費者模式)

ArrayBlockingQueue在構造時需要指定容量,並可以選擇是否需要公平性,如果公平參數被設置true,等待時間最長的線程會優先得到處理(其實是通過將ReentrantLock設置為true來達到這種公平性的:即等待時間最長的線程會先操作)。

 PriorityBlockingQueue是一個帶優先級的隊列,而不是先進先出隊列。元素按優先級順序被移除,該隊列也沒有上限(PriorityBlockingQueue是對PriorityQueue的再次包裝,是基於堆數據結構的,而PriorityQueue是沒有容量限制的,與ArrayList一樣,所以在優先阻塞隊列上put時是不會受阻的。雖然此隊列邏輯上是無界的,但是由於資源被耗盡,所以試圖執行添加操作可能會導致OutOfMemoryError),但是如果隊列為空,那么取元素的操作take就會阻塞,所以它的檢索操作take是受阻的。另外,進入該隊列的元素要具有比較能力(實現Comparable接口,重寫conpareTo方法)。

 DelayQueue(基於PriorityQueue實現的)是一個存放Delayed元素的無界阻塞隊列,只有在延遲期滿時才能從中提取元素。該隊列的頭部是延遲期滿后保存時間最長的Delayed元素。如果延遲期都還沒有滿,則隊列沒有頭部,並且poll將返回null。當一個元素的getDelay(TimeUnit.NANOSECONDS)方法返回一個小於或等於零的值時,則出現期滿,poll就可以移除這個元素了,此隊列不允許使用null元素。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM