轉載請注明源出處: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的類似,不再進行介紹。