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. MATLAB accumarray

    先看看subs和val的具体内容 subs = [1 1 1; 2 1 2; 2 3 2; 2 1 2; 2 3 2]; subs = 1     1     1 2     1     2 2    ...

  2. python小白——进阶之路——day4天-———流程控制while if循环

    # ### 代码块: 以冒号作为开始,用缩进来划分作用域,这个整体叫做代码块 if 5 == 5: print(1) print(2) # 注意点: 要么全部使用4个空格,要么全部使用1个缩进 ,这样 ...

  3. 使用exec和sp_executesql动态执行SQL语句(转载)

    当需要根据外部输入的参数来决定要执行的SQL语句时,常常需要动态来构造SQL查询语句,个人觉得用得比较多的地方就是分页存储过程和执行搜索查询的SQL语句.一个比较通用的分页存储过程,可能需要传入表名, ...

  4. pyspider爬虫框架

    特点: 去重处理,结果监控,多进程处理,pyquery提取,错误重试,webUI管理,代码简洁,JS渲染 安装: anaconda里边没搜到pyspider,所以手动安装 查看pyspider的命令: ...

  5. 基本环境安装: Centos7+Java+Hadoop+Spark+HBase+ES+Azkaban

    1.  安装VM14的方法在 人工智能标签中的<跨平台踩的大坑有提到> 2. CentOS分区设置: /boot:1024M,标准分区格式创建. swap:4096M,标准分区格式创建. ...

  6. 4月11日java多线程4

    继昨天学习了线程池之后,今天学习了多线程内的锁Lock. 定义方法: ReentrantLock queueLock = new ReentrantLock(); //可重入锁 ReentrantRe ...

  7. python之常用模块一(time、random、os、sys)

    摘要:时间模块time .随机模块random .os模块.sys模块 一.时间模块 三种格式 时间戳时间:浮点数 单位为秒 时间戳起始时间: 1970.1.1 0:0:0 英国伦敦时间 1970.1 ...

  8. MySQL——修改一个表的自增值

    语句 alter table <table name> auto_increment=<value>; 示例 mysql; Query OK, rows affected (0 ...

  9. MT【318】分式不等式双代换

    已知$a,b>0$且$\dfrac{1}{a}+\dfrac{1}{b}=\dfrac{2}{3}$,求$\dfrac{1}{a-1}+\dfrac{4}{b-1}$的最小值. 解:令$m=\d ...

  10. Linux(Ubuntu)换apt-get源

    在虚拟机安装完Ubuntu后,因为apt-get命令默认的服务器在国外会很慢,换成国内的会快很多 选一个国内镜像源,以清华大学开源镜像为例,要选对应的Ubuntu版本 网站链接https://mirr ...