PriorityQueue位于Java util包中,观其名字前半部分的单词Priority是优先的意思,实际上这个队列就是具有“优先级”。既然具有优先级的特性,那么就得有个前后排序的“规则”。所以其接受的类需要实现Comparable 接口。

API

1.构造函数

PriorityQueue()
PriorityQueue(Collection<? extends E> c)
PriorityQueue(int initialCapacity)
PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
PriorityQueue(PriorityQueue<? extends E> c)
PriorityQueue(SortedSet<? extends E> c)

2.常用功能函数

方法名 功能描述
add(E e) 添加元素
clear() 清空
contains(Object o) 检查是否包含当前参数元素
offer(E e) 添加元素
peek() 读取元素,(不删除)
poll() 取出元素,(删除)
remove(Object o) 删除指定元素
size() 返回长度

用法示例

上面提到具有优先级,那么这里举个例子。我在上高中的时候,每月分一次班级,老师会按照本月月考的成绩来让每位同学优先选择自己心仪的座位。这里所有的同学便是一个队列;每次喊一个人进来挑选座位,这便是出对的操作;成绩由前至后,这边是优先的策略。

  • 代码示例如下:
public class PriorityQueueTest {
public static void main(String[] args) { final PriorityQueue<Student> queue=new PriorityQueue<>(); Student p1=new Student(95,"张三");
Student p2=new Student(89,"李四");
Student p3=new Student(89,"李四");
Student p4=new Student(67,"王五");
Student p5=new Student(92,"赵六");
queue.add(p1);
queue.add(p2);
queue.add(p3);//add 和offer效果一样。
queue.offer(p4);//add 方法实现,其实就是调用了offer
queue.offer(p5) for (Student Student : queue) {
System.out.println(Student.toString());
} System.out.println("---------------------");
while(!queue.isEmpty()){
System.out.println(queue.poll());
}
} }
class Student implements Comparable{
private int score;
private String name; public Student(int age,String name){
this.score=age;
this.name=name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString(){
return "姓名:"+name+"-"+score+"分";
} @Override
public int compareTo(Object o) {
Student current=(Student)o;
if(current.getScore()>this.score){
return 1;
}else if(current.getScore()==this.score){
return 0;
}
return -1;
}
}
  • 运行结果:
    姓名:张三-95分
    姓名:赵六-92分
    姓名:王五-67分
    姓名:李四-89分
    ---------按顺序出队选座位------------
    姓名:张三-95分
    姓名:赵六-92分
    姓名:李四-89分
    姓名:李四-89分
    姓名:王五-67分

从第一部分输出可以看出,学生入队并不是 按顺序的,而在poll出来的时候是按顺序出队的,这里确实实现了分数高这优先选座位的效果,poll方法返回的总是队列剩余学生中分数最高的。

安全性

查看PriorityQueue类的源码,会发现增加操作,并不是原子操作。没有使用任何锁。那么,如果是在多线程环境,肯定是不安全的。下面给出例子,开启多个线程,调用同一个方法对Queue进行添加元素。然后输出结果。

public class PriorityQueueTest {

    static final PriorityQueue<Integer> queue=new PriorityQueue<>();
/**
* 向队列中插入元素
* @param number
*/
public void add(int number){
if(!queue.contains(number)){
System.out.println(Thread.currentThread()+":"+number);
queue.add(number);
}
} public static void main(String[] args) throws InterruptedException {
final PriorityQueueTest qt=new PriorityQueueTest();
final Random r=new Random();
Thread t1=new Thread(){
public void run(){
System.out.println("t1开始运行...");
for(int i=0;i<10;i++){
qt.add(r.nextInt(10));
}
}
};
Thread t2=new Thread(){
public void run(){
System.out.println("t2开始运行...");
for(int i=0;i<10;i++){
qt.add(r.nextInt(10));
}
}
};
Thread t3=new Thread(){
public void run(){
System.out.println("t3开始运行...");
for(int i=0;i<10;i++){
qt.add(r.nextInt(10));
}
}
};
t1.start();
t2.start();
t3.start();
t1.join();
t2.join();
t3.join();
System.out.println("------ 运行结果 ---------");
while(!queue.isEmpty()){
System.out.println(queue.poll());
}
}
}
  • 运行结果
    t2开始运行...
    t3开始运行...
    t1开始运行...
    ------ 运行结果 ---------
    0
    1
    1
    2
    3
    4
    5
    6
    7
    8
    9
    9

结果中我们可以看到,具有两个1,两个9.这是不符合我们预期的,我们预期的是not contains 才插入,现在的出现的了重复的。上面的例子只需要在add方法上加锁,才可以达到我们预期的效果。所以说,PriorityQueue非线程安全的。
[1]: http://www.cnblogs.com/demingblog/p/6474865.html

Java Queue之PriorityQueue的更多相关文章

  1. # Java Queue系列之PriorityQueue

    在上一篇中我用一张图来梳理了一下Java中的各种Queue之间的关系.这里介绍下PriorityQueue.PriorityQueue位于Java util包中,观其名字前半部分的单词Priority ...

  2. 算法竞赛中的常用JAVA API:PriorityQueue(优先队列)(转载)

    算法竞赛中的常用JAVA API:PriorityQueue(优先队列) PriorityQueue 翻译过来就是优先队列,本质是一个堆, 默认情况下堆顶每次都保留最小值,每插入一个元素,仍动态维护堆 ...

  3. atitit. java queue 队列体系and自定义基于数据库的队列总结o7t

    atitit. java queue 队列体系and自定义基于数据库的队列总结o7t 1. 阻塞队列和非阻塞队列 1 2. java.util.Queue接口, 1 3. ConcurrentLink ...

  4. Java学习笔记--PriorityQueue(优先队列)(堆)

    PriorityQueue(优先队列)实际上是一个堆(不指定Comparator时默认为最小堆)队列既可以根据元素的自然顺序来排序,也可以根据 Comparator来设置排序规则.队列的头是按指定排序 ...

  5. java Queue中 add/offer,element/peek,remove/poll区别

    转自https://blog.csdn.net/u012050154/article/details/60572567 java Queue中 add/offer,element/peek,remov ...

  6. (17)线程队列---queue LifoQueue PriorityQueue

    线程常用队列有: queue LifoQueue PriorityQueue 语法: 大致和进程队列语法一致 put 往队列当中放值,超过队列长度,直接加阻塞 get 如果获取不到加阻塞 put_no ...

  7. LinkedList、Stack、Queue、PriorityQueue的总结

    1.这几种容器的特点 都是按照顺序来存储元素. 取元素的时候的不同点: LinkedList:按照下标随意取元素 Stack:后进先出取元素 Queue:先进先出取元素 PriorityQueue:按 ...

  8. atitit. java queue 队列体系and自己定义基于数据库的队列总结o7t

    atitit. java queue 队列体系and自己定义基于数据库的队列总结o7t 1. 堵塞队列和非堵塞队列 1 2. java.util.Queue接口. 1 3. ConcurrentLin ...

  9. Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)

    Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...

随机推荐

  1. leetcode 169. Majority Element 、229. Majority Element II

    169. Majority Element 求超过数组个数一半的数 可以使用hash解决,时间复杂度为O(n),但空间复杂度也为O(n) class Solution { public: int ma ...

  2. springBoot集成redisCluster

    本文主要内容:springBoot简介,在SpringBoot中如何集成Redis,可配置Redis集群. 关于SpringBoot 你想要的,这里都有:https://spring.io/proje ...

  3. Codeforces Round #551 (Div. 2) EF Solution

    E. Serval and Snake 对于一个矩形,如果蛇的一条边与它相交,就意味着这条蛇从矩形内穿到矩形外,或者从矩形外穿到矩形内.所以如果某个矩形的答案为偶数,意味着蛇的头尾在矩形的同一侧(内或 ...

  4. 1 Introduction

    1. Introduction 1.1. License Flowable is distributed under the Apache V2 license. 1.2. Download http ...

  5. 02-JavaScript语法

    JavaScript语法 1.JS的引入 1- 直接在<script>标签下引入 <!DOCTYPE html> <html lang="zh-CN" ...

  6. Django admin注册model究竟要怎么写才优雅 批量注册model

    比如在Django admin 注册models时,会用到. 对于APP里自带的models,可以使用这种方式注册. from django.contrib import admin # Regist ...

  7. Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析

    一.一个请求来到Django 的生命周期   FBV 不讨论 CBV: 请求被代理转发到uwsgi: 开始Django的流程: 首先经过中间件process_request (session等) 然后 ...

  8. 使用tar解压的时候提示:gzip: stdin: not in gzip format

    问题背景 我是在CentOS上面使用wget命令下载JDK8的源码之后,使用tar命令解压下载的文件,结果出现这样的错误: [root@VM_0_8_centos src]# wget https:/ ...

  9. Django(一) 安装使用基础

    大纲 安装Django 1.创建Django工程 2.创建Django app 3.写一个简单的登录注册相应页面 4.获取用户请求信息并处理 5.前后端交互 6.Django 请求 生命周期  跳转到 ...

  10. 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)

    [BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...