1. 程式人生 > >Java之集合(二十二)PriorityBlockingQueue

Java之集合(二十二)PriorityBlockingQueue

www. 叠代 html 數組 最小 editor 進行 () http

  轉載請註明源出處:http://www.cnblogs.com/lighten/p/7510799.html

1.前言

  本章介紹阻塞隊列PriorityBlockingQueue。這是一個無界有序的阻塞隊列,排序規則和之前介紹的PriorityQueue一致,只是增加了阻塞操作。同樣的該隊列不支持插入null元素,同時不支持插入非comparable的對象。它的叠代器並不保證隊列保持任何特定的順序,如果想要順序遍歷,考慮使用Arrays.sort(pq.toArray())。該類不保證同等優先級的元素順序,如果你想要強制順序,就需要考慮自定義順序或者是Comparator使用第二個比較屬性。

2.PriorityBlockingQueue

2.1 數據結構

技術分享

  DEFAULT_INITIAL_CAPACITY:默認隊列容量11

  MAX_ARRAY_SIZE:最大可分配隊列容量Integer.MAX_VALUE - 8,減8是因為有的VM實現在數組頭有些內容

  queue:隊列元素數組。平衡二叉堆實現,父節點下標是n,左節點則是2n+1,右節點是2n+2。最小的元素在最前面

  size:當前隊列中元素的個數

  comparator:決定隊列中元素先後順序的比較器

  lock:所有public方法的鎖

  notEmpty:隊列為空時的阻塞條件

  allocationSpinLock:擴容數組分配資源時的自旋鎖,CAS需要

  q:PriorityQueue只用於序列化的時候,為了兼容之前的版本。只有在序列化和反序列化的時候不為null。

2.2 基本操作

  放入一個元素

技術分享

  和PriorityQueue的實現基本一致區別就是在於加鎖了,並發出了非空信號喚醒阻塞的獲取線程。具體操作原理看:PriorityQueue。這裏值得一說的就是tryGrow的實現,其用了一個while循環來處理,下面是具體實現。

技術分享

  其先放開了鎖,然後通過CAS設置allocationSpinLock來判斷哪個線程獲得了擴容權限,如果沒搶到權限就會讓出CPU使用權。最後還是要鎖住開始真正的擴容。擴容權限爭取到了就是計算大小,分配數組。暫不肯定為什麽這麽麻煩要分配數組的時候釋放鎖,暫猜測這樣做效率會更高。

  其它的操作過程都和PriorityQueue的類似,不再進行介紹。

Java之集合(二十二)PriorityBlockingQueue