PriorityBlockingQueue是一个基于优先级堆的*的并发安全的优先级队列(FIFO),队列的元素按照其自然顺序进行排序,或者根据构造队列时提供的 Comparator 进行排序,具体取决于所使用的构造方法。
实现原理
PriorityBlockingQueue通过使用堆这种数据结构实现将队列中的元素按照某种排序规则进行排序,从而改变先进先出的队列顺序,提供开发者改变队列中元素的顺序的能力。队列中的元素必须是可比较的,即实现Comparable接口,或者在构建函数时提供可对队列元素进行比较的Comparator对象。
PriorityBlockingQueue类是JDK提供的优先级队列 本身是线程安全的 内部使用显示锁 保证线程安全
PriorityBlockingQueue存储的对象必须是实现Comparable接口的 因为PriorityBlockingQueue队列会根据内部存储的每一个元素的compareTo方法比较每个元素的大小
这样在take出来的时候会根据优先级 将优先级最小的最先取出
public static PriorityBlockingQueue<User> queue = new PriorityBlockingQueue<User>(); public static void main(String[] args) { queue.add(new User(1,"wu")); queue.add(new User(5,"wu5")); queue.add(new User(23,"wu23")); queue.add(new User(55,"wu55")); queue.add(new User(9,"wu9")); queue.add(new User(3,"wu3")); for (User user : queue) { try { System.out.println(queue.take().name); } catch (InterruptedException e) { e.printStackTrace(); } } } //静态内部类 static class User implements Comparable<User>{ public User(int age,String name) { this.age = age; this.name = name; } int age; String name; @Override public int compareTo(User o) { return this.age > o.age ? -1 : 1; } }
输出结果
wu
wu3
wu5
wu9
wu23
wu55
案例2:
package com.bjsxt.base.coll013; public class Task implements Comparable<Task>{ private int id ; private String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int compareTo(Task task) { return this.id > task.id ? 1 : (this.id < task.id ? -1 : 0); } public String toString(){ return this.id + "," + this.name; } }
package com.bjsxt.base.coll013; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.concurrent.PriorityBlockingQueue; public class UsePriorityBlockingQueue { public static void main(String[] args) throws Exception{ PriorityBlockingQueue<Task> q = new PriorityBlockingQueue<Task>(); Task t1 = new Task(); t1.setId(3); t1.setName("id为3"); Task t2 = new Task(); t2.setId(4); t2.setName("id为4"); Task t3 = new Task(); t3.setId(1); t3.setName("id为1"); //return this.id > task.id ? 1 : 0; q.add(t1); //3 q.add(t2); //4 q.add(t3); //1 // 1 3 4 System.out.println("容器:" + q); System.out.println(q.take().getId()); System.out.println("容器:" + q); // System.out.println(q.take().getId()); // System.out.println(q.take().getId()); } }
输出的结果是:
容器:[1,id为1, 4,id为4, 3,id为3]
1
容器:[3,id为3, 4,id为4]
从输出结果可以看出在没有调用take方法之前队列是没有进行排序比较的的,调用take进行排序比较获得优先级最大或者最低的元素,在add添加元素的时候是没有排序的,只有在调用take方法的时候才进行排序获得优先级最高的元素