Java之集合(二十二)PriorityBlockingQueue
轉載請註明源出處: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