【BlockingQueue】PriorityBlockingQueue

内部结构

内部维护了lock和notEmpty两个属性
1.比较的对象必须实现comparable<T>接口,底层用数组实现,小值排左边,大值排右边
2.底层用数组实现,无界队列
3.take()方法是阻塞的,如果队列中为空, 会调用notEmpty.await()方法。
4.采用和ArrayBlockingQueue一样的独占锁,控制1次只有一个线程可以操作入队和出队,priority队列只有notEmpty,而没有notFull,因为是无界队列,会自动扩容
5.任何的put相关的队列都不会阻塞,与take相关的操作会阻塞
6.PriorityBlockingQueue始终保证出队的元素是优先级最高的元素,并且可以定制优先级的规则,内部通过使用一个二叉树最小堆算法来维护内部数组,这个数组是可扩容的,当当前元素个数>=最大容量时候会通过算法扩容
7.默认情况下元素采用自然顺序升序排序,当然我们也可以通过构造函数来指定Comparator来对元素进行排序。需要注意的是PriorityBlockingQueue不能保证同优先级元素的顺序


最小堆的构建:
1.插入
a.将元素a插入到队列尾部n处,首先与其父节点k比较,如果大于,则将a放在n处,结束
b.如果a小于父节点,则将父节点k放在n处,继续拿a与k的父节点pa比较,如果大于,则将a放在k处,结束
c.如果小于,则继续与pa的父节点pa1比较,以此类推,直到比较到堆的头部,也就是数组的下标0

2.删除
a.删除头节点a后,比较堆尾部节点k与左右子节点的大小,将小的节点提升为头节点,此时产生了空穴
b.继续比较空穴的子节点,并将小的节点放在空穴处,以此类推

队列中创建最小队的方法:
private static <T> void siftUpComparable(int k, T x, Object[] array) {
    Comparable<? super T> key = (Comparable<? super T>) x;
    //队列元素个数>0则判断插入位置,否者直接入队(7)
    while (k > 0) {
        int parent = (k - 1) >>> 1; //父节点 (k-1)/2
        Object e = array[parent];
        if (key.compareTo((T) e) >= 0)
            break;
        array[k] = e;
        k = parent;
    }
    array[k] = key;(8)
}

调用poll等方法时,会移除队列的第一项,然后将最后一项移动到队首,并调整队的顺序:

private static <T> void siftDownComparable(int k, T x, Object[] array,
                                            int n) {
     if (n > 0) {
         Comparable<? super T> key = (Comparable<? super T>)x;
         int half = n >>> 1;           // loop while a non-leaf
         while (k < half) {
             int child = (k << 1) + 1;   //k节点的左子节点
             Object c = array[child];(5)
             int right = child + 1;(6)  //k节点的右子节点
             if (right < n &&
                 ((Comparable<? super T>) c).compareTo((T) array[right]) > 0)(7)
                 c = array[child = right]; //取两个子节点中最小的一个值
             if (key.compareTo((T) c) <= 0)(8) //再和数组中最后一个值比较,如果小于,则将数组中最后一个位置n的值移动到队列头部k位置,否则将头部位置替换为左右子节点中较小的一个c,再比较n的值和c的大小。
                 break;
             array[k] = c;
             k = child;
         }
         array[k] = key;(9)
     }
 }

【参考博客】
http://www.importnew.com/25541.html
https://www.jianshu.com/p/43954715aa28【有二叉队的详细解释】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容

  • 自我提升阅读打卡第174天(10月7日) 今天晚上重读了《赢在执行》的第一,第二章。重温之余,感慨良多,其中最认同...
    vv167阅读 374评论 0 1
  • 《人生低谷期》 这大概是我人生低谷期开始的第188天左右吧,很久没写东西了忽然想写点什么 现在的状态仿...
    一只鲸鱼的过去阅读 245评论 2 1
  • 这是你和对方一起探讨的。适不适合对方。 1. 我们要不要孩子?如果要,主要由谁负责? 2. 我们的赚钱能力及目标是...
    cancat001阅读 18,368评论 1 8