PriorityQueue和PriorityBlockingQueue

简介

Queue一般来说都是FIFO的,当然之前我们也介绍过Deque可以做为栈来使用。今天我们介绍一种PriorityQueue,可以安装对象的自然顺序或者自定义顺序在Queue中进行排序。

PriorityQueue

先看PriorityQueue,这个Queue继承自AbstractQueue,是非线程安全的。

PriorityQueue的容量是unbounded的,也就是说它没有容量大小的限制,所以你可以无限添加元素,如果添加的太多,最后会报OutOfMemoryError异常。

这里教大家一个识别的技能,只要集合类中带有CAPACITY的,其底层实现大部分都是数组,因为只有数组才有capacity,当然也有例外,比如LinkedBlockingDeque。

只要集合类中带有comparator的,那么这个集合一定是个有序集合。

我们看下PriorityQueue:

private static final int DEFAULT_INITIAL_CAPACITY = 11;
private final Comparator<? super E> comparator;

定义了初始Capacity和comparator,那么PriorityQueue的底层实现就是Array,并且它是一个有序集合。

有序集合默认情况下是按照natural ordering来排序的,如果你传入了 Comparator,则会按照你指定的方式进行排序,我们看两个排序的例子:

@Slf4j
public class PriorityQueueUsage { @Test
public void usePriorityQueue(){
PriorityQueue<Integer> integerQueue = new PriorityQueue<>(); integerQueue.add(1);
integerQueue.add(3);
integerQueue.add(2); int first = integerQueue.poll();
int second = integerQueue.poll();
int third = integerQueue.poll(); log.info("{},{},{}",first,second,third);
} @Test
public void usePriorityQueueWithComparator(){
PriorityQueue<Integer> integerQueue = new PriorityQueue<>((a,b)-> b-a);
integerQueue.add(1);
integerQueue.add(3);
integerQueue.add(2); int first = integerQueue.poll();
int second = integerQueue.poll();
int third = integerQueue.poll(); log.info("{},{},{}",first,second,third);
}
}

默认情况下会按照升序排列,第二个例子中我们传入了一个逆序的Comparator,则会按照逆序排列。

PriorityBlockingQueue

PriorityBlockingQueue是一个BlockingQueue,所以它是线程安全的。

我们考虑这样一个问题,如果两个对象的natural ordering或者Comparator的顺序是一样的话,两个对象的顺序还是固定的吗?

出现这种情况,默认顺序是不能确定的,但是我们可以这样封装对象,让对象可以在排序顺序一致的情况下,再按照创建顺序先进先出FIFO的二次排序:

public class FIFOEntry<E extends Comparable<? super E>>
implements Comparable<FIFOEntry<E>> {
static final AtomicLong seq = new AtomicLong(0);
final long seqNum;
final E entry;
public FIFOEntry(E entry) {
seqNum = seq.getAndIncrement();
this.entry = entry;
}
public E getEntry() { return entry; }
public int compareTo(FIFOEntry<E> other) {
int res = entry.compareTo(other.entry);
if (res == 0 && other.entry != this.entry)
res = (seqNum < other.seqNum ? -1 : 1);
return res;
}
}

上面的例子中,先比较两个Entry的natural ordering,如果一致的话,再按照seqNum进行排序。

本文的例子https://github.com/ddean2009/learn-java-collections

欢迎关注我的公众号:程序那些事,更多精彩等着您!

更多内容请访问 www.flydean.com

PriorityQueue和PriorityBlockingQueue的更多相关文章

  1. java并发程序——BlockingQueue

    概述 BlockingQueue顾名思义'阻塞的队列',是指在:队列的读取行为被阻塞直到队列不为空时,队列的写入行为被阻塞直到队列不满时.BlockingQueue是java.util.concurr ...

  2. DelayQueue使用

    假设现有如下的使用场景: a) 关闭空闲连接.服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之. b) 缓存.缓存中的对象,超过了空闲时间,需要从缓存中移出. c) 任务超时处理.在网络协议滑 ...

  3. Java数据结构和算法(五)二叉排序树(BST)

    Java数据结构和算法(五)二叉排序树(BST) 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 二叉排序树(Binary S ...

  4. Java多线程(六) —— 线程并发库之并发容器

    参考文献: http://www.blogjava.net/xylz/archive/2010/07/19/326527.html 一.ConcurrentMap API 从这一节开始正式进入并发容器 ...

  5. Activemq API使用(整合spring)

    整合spring之后,主要用的就是org.springframework.jms.core.JmsTemplate的API了,在spring-jms-xxx.jar中. 引入整合需要的jar包: &l ...

  6. Java集合大全

    上图为整理的集合类图关系,带对号标志的为线程安全类. 区别说明: 1.List Set Map Queue的区别List: 有序,可以多个元素引用相同的对象Set: 无序,不重复,不可以多个元素引用相 ...

  7. 线程池的使用(ThreadPoolExecutor详解)

    为什么要使用线程池? 线程是一个操作系统概念.操作系统负责这个线程的创建.挂起.运行.阻塞和终结操作.而操作系统创建线程.切换线程状态.终结线程都要进行CPU调度——这是一个耗费时间和系统资源的事情. ...

  8. JDK源码那些事儿之DelayQueue

    作为阻塞队列的一员,DelayQueue(延迟队列)由于其特殊含义而使用在特定的场景之中,主要在于Delay这个词上,那么其内部是如何实现的呢?今天一起通过DelayQueue的源码来看一看其是如何完 ...

  9. 深入浅出 Java Concurrency (23): 并发容器 part 8 可阻塞的BlockingQueue (3)[转]

    在Set中有一个排序的集合SortedSet,用来保存按照自然顺序排列的对象.Queue中同样引入了一个支持排序的FIFO模型. 并发队列与Queue简介 中介绍了,PriorityQueue和Pri ...

  10. 深入浅出 Java Concurrency (19): 并发容器 part 4 并发队列与Queue简介[转]

    Queue是JDK 5以后引入的新的集合类,它属于Java Collections Framework的成员,在Collection集合中和List/Set是同一级别的接口.通常来讲Queue描述的是 ...

随机推荐

  1. mongodb(2022)

    了解 文档数据库MongoDB用于记录文档结构的数据,如JSON.XML结构的数据.一条文档就是一条记录(含数据和数据结构),一条记录里可以包含若干个键值对.键值对由键和值两部分组成,键又叫做字段.键 ...

  2. Django之第三方平台QQ授权登录的实现

    接入指南:https://wiki.connect.qq.com/成为开发者 准备工作 成为开发者 首先要有一个开发者账号,https://connect.qq.com/ 登录后点击用户头像,修改个人 ...

  3. toml格式配置文件介绍

    toml官方wik toml官方文档 此次文档是以v1.0.0为例,进行说明的.如果使用到的版本不同,直接去官方文档中找对应的版本即可. 谈到配置文件,大家都能说出来好几种,比如常见的ini.xml. ...

  4. 【Azure 事件中心】Azure Event Hub中的数据能不能存储大于7天呢?如果7天之后是不是会自动删除呢?

    问题描述 Event Hub中有个retention的设置为7天,有没有办法增大这个Retention的时间? 如果没办法,是不是超过7天的数据就会被删除? 问题解答 因为Azure Event Hu ...

  5. 【Azure 应用服务】App Service For Linux 环境中,如何从App Service中获取GitHub私有库(Private Repos)的Deploy Key(RSA key)呢?

    问题描述 为App Service For Linux配置CI/CD,源代码在GitHub私有库中,在发布时候报错 Cannot find SourceControlToken with name B ...

  6. CPNtools协议建模安全分析(一)

    本文根据最近整理的CPNtools论文和CPNtools官网上的说明,以及参照了乌克兰敖德萨 ---国家电信研究院运输和通信部关于   电信系统协议仿真关于CPNtools的学生讲义.基于此和和自己的 ...

  7. obs 录制教程 手机录屏用 向日葵 手机投屏 能用有线用有线的连接

    obs 录制教程 手机录屏用 向日葵 手机投屏 稍微有点卡 华为手机有个投屏 笔记本不支持这个 miracast 淘宝有卖 投屏设备的,搜 miracast 100多米 免费的就用向日葵就得了. 最新 ...

  8. day10-中文乱码处理

    中文乱码处理 1.问题抛出 当表单提交的数据为中文时,会出现乱码: (1)Monster.java: package com.li.web.datavalid.entity; import org.h ...

  9. HISI3520DV300 折腾记录(二)之《内存映射、存储(DDRC,FMC)、启动模式分析》

    PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明   本文作为本人csdn blog的主站的备份.(Bl ...

  10. 8、Linux CentOS 安装.Net Core 3.1

    1.添加密钥 将 Microsoft 包签名密钥添加到受信任密钥列表,并添加 Microsoft 包存储库. 打开终端并运行以下命令: sudo rpm -Uvh https://packages.m ...