PriorityQueue和PriorityBlockingQueue
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的更多相关文章
- java并发程序——BlockingQueue
概述 BlockingQueue顾名思义'阻塞的队列',是指在:队列的读取行为被阻塞直到队列不为空时,队列的写入行为被阻塞直到队列不满时.BlockingQueue是java.util.concurr ...
- DelayQueue使用
假设现有如下的使用场景: a) 关闭空闲连接.服务器中,有很多客户端的连接,空闲一段时间之后需要关闭之. b) 缓存.缓存中的对象,超过了空闲时间,需要从缓存中移出. c) 任务超时处理.在网络协议滑 ...
- Java数据结构和算法(五)二叉排序树(BST)
Java数据结构和算法(五)二叉排序树(BST) 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 二叉排序树(Binary S ...
- Java多线程(六) —— 线程并发库之并发容器
参考文献: http://www.blogjava.net/xylz/archive/2010/07/19/326527.html 一.ConcurrentMap API 从这一节开始正式进入并发容器 ...
- Activemq API使用(整合spring)
整合spring之后,主要用的就是org.springframework.jms.core.JmsTemplate的API了,在spring-jms-xxx.jar中. 引入整合需要的jar包: &l ...
- Java集合大全
上图为整理的集合类图关系,带对号标志的为线程安全类. 区别说明: 1.List Set Map Queue的区别List: 有序,可以多个元素引用相同的对象Set: 无序,不重复,不可以多个元素引用相 ...
- 线程池的使用(ThreadPoolExecutor详解)
为什么要使用线程池? 线程是一个操作系统概念.操作系统负责这个线程的创建.挂起.运行.阻塞和终结操作.而操作系统创建线程.切换线程状态.终结线程都要进行CPU调度——这是一个耗费时间和系统资源的事情. ...
- JDK源码那些事儿之DelayQueue
作为阻塞队列的一员,DelayQueue(延迟队列)由于其特殊含义而使用在特定的场景之中,主要在于Delay这个词上,那么其内部是如何实现的呢?今天一起通过DelayQueue的源码来看一看其是如何完 ...
- 深入浅出 Java Concurrency (23): 并发容器 part 8 可阻塞的BlockingQueue (3)[转]
在Set中有一个排序的集合SortedSet,用来保存按照自然顺序排列的对象.Queue中同样引入了一个支持排序的FIFO模型. 并发队列与Queue简介 中介绍了,PriorityQueue和Pri ...
- 深入浅出 Java Concurrency (19): 并发容器 part 4 并发队列与Queue简介[转]
Queue是JDK 5以后引入的新的集合类,它属于Java Collections Framework的成员,在Collection集合中和List/Set是同一级别的接口.通常来讲Queue描述的是 ...
随机推荐
- 基于java的图书管理系统
基于java的图书管理系统 项目概述 使用数组存储数据实现一个图书管理系统,完成的功能有增加图书.删除图书.更新图书.查询图书.图书列表.增删改查 登陆注册 首页 图书更新 图书列表 开发工具/技术 ...
- 【Azure 应用服务】FTP 部署 Vue 生成的静态文件至 Linux App Service 后,访问App Service URL依旧显示Azure默认页面问题
问题描述 将 JS项目打包为静态文件后,通过 FTP 上传到 App Service For Linux 的 /home/site/wwwroot文件夹中.但打开App Service URL 后依旧 ...
- 【Azure 应用服务】App Service 项目部署成功后,应用连接 Azure Redis时报错 Could not get a resource from the pool
问题描述 App Service 项目部署成功后,需要连接到同在云上的Redis服务, Redis启动了专用终结点,只能在于Redis同一个VNET(虚拟网络)的资源能够访问.在进入App Servi ...
- Educational Codeforces Round 145 (Rated for Div. 2)C. Sum on Subarrays(构造)
很意思的一道构造题 题意:给一个\(n.k\),让构造长度为n的数组满足,子数组为整数的个数为k个,负数的为\(k-(n+1)* n/2\),每个数的范围为\([-1000,1000]\) 这种构造题 ...
- TLS原理与实践(三)tls1.3
主页 个人微信公众号:密码应用技术实战 个人博客园首页:https://www.cnblogs.com/informatics/ 引言 tls1.2作为主流的网路安全协议,被广泛应用,但tls1.2仍 ...
- 远程服务调用(RPC与Rest本质区别)
一.背景 远程服务将计算机程序的工作范围从单机扩展到网络,从本地延伸至远程,是构建分布式系统的首要基础.远程服务调用(Remote Procedure Call,RPC)在计算机科学中已经存在了超过四 ...
- java项目-尚硅谷项目三员工调度系统
导入工具类和数据 创建TeamSchedule项目,com.atguigu.team. view,com.atguigu.team.service,com.atguigu.team.domain包 , ...
- favorite 单词学习 主要是发音 fa - vor - it 注意 ri不连读 是自然带出来的r的尾音
favorite 单词学习 主要注意发音 [ ˈfeɪ v(ə)r ɪt ] 主要是发音 fa - vor - it 注意 ri不连读 是自然带出来的r的尾音 favor : 来自拉丁语favere, ...
- WINDOWS.H already included. MFC apps must not #include Windows.h
做C++.C#和C++/CLI的混合编程有一段时间了,填了不少的坑. 今天又遇到一错误,想着挺容易就解决,估计是大脑疲惫,折腾许久才找到原因. 错误: 错误 C1189 #error: WINDOWS ...
- 键鼠共享工具使用(软KVM)-barrier(symless开源版)
作用:通过软件方式,实现KVM,即一套键盘鼠标可以控制多台电脑,并可以进行粘贴板共享. 1.安装 打开https://github.com/debauchee/barrier,进releases下载对 ...