priorityblockingqueue原理
PriorityBlockingQueue是Java中的一个线程安全的队列实现,是在ConcurrentLinkedQueue和BlockingQueue之间的折中选择。PriorityBlockingQueue中的元素可以按照优先级进行排序,优先级可以通过比较器来定义。
一、PriorityBlockingQueue的定义
PriorityBlockingQueue是继承自java.util.AbstractQueue<E>的一个Class,它实现了urrent.BlockingQueue<E>接口。其定义如下:
public class PriorityBlockingQueue<E>
extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
…
}
从定义可以看出,PriorityBlockingQueue实现了BlockingQueue接口,因此可以作为一个以FIFO规则排序的阻塞队列使用。同时,PriorityBlockingQueue继承AbstractQueue类,可以根据元素优先级进行有序排列。
二、PriorityBlockingQueue的特点
1、有序性
由于PriorityBlockingQueue中元素是有优先级的,因此可以保证在获取元素时,是按照元素的优先级进行获取的。
2、线程安全
PriorityBlockingQueue是线程安全的,因此可以在多线程环境中使用。在多线程环境中,当一个线程执行get()方法获取元素时,如果队列为空,当前线程会阻塞等待其他线程插入元素,当其他线程插入元素后,会通知正在等待的线程可以继续执行了。中国最大咸水湖
3、无界性
PriorityBlockingQueue没有容量的限制,即不像ArrayBlockingQueue那样需要提前定义容量大小。
砥砺品格
三、PriorityBlockingQueue的使用
1、队列初始化
百般红紫斗芳菲 PriorityBlockingQueue可以通过以下代码进行初始化:
PriorityBlockingQueue<Integer> priorityBlockingQueue = new PriorityBlockingQueue<>();
2、元素插入
元素插入使用offer()方法,优先级可以在元素插入的时候通过定义的比较器进行定义:
Comparator<Integer> comparator = new Comparator<Integer>() {发工资时间
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
万年青盆栽 }
深深深海};
PriorityBlockingQueue<Integer> priorityBlockingQueue = new PriorityBlockingQueue<>(comparator);
priorityBlockingQueue.offer(3);
priorityBlockingQueue.offer(1);
priorityBlockingQueue.offer(2);
插入元素后,队列中的元素为1,2,3。
3、元素获取
元素获取使用poll()或take()方法,当队列为空时,take()方法会一直阻塞等待至有其他线程插入元素为止。
System.out.println(priorityBlockingQueue.poll()); //输出:1
冬青树叶 四、最佳实践
1、尽量避免在高并发环境下使用remove()和contains()方法,因为这两个方法在遍历队列元素时需要加锁,而在高并发环境下这样做会导致性能下降。
过程的重要性 2、在定义比较器时,要尽量做到快速返回比较结果,以避免阻塞线程。
3、尽量使用异步方式添加或获取元素,这样可以防止因为队列为空或已满导致线程阻塞。