概述
PriorityBlockingQueue是带优先级的无界阻塞队列,每次出队都返回优先级最高或者最低的元素。
其内部是使用平衡二叉树堆实现的,所以直接遍历队列元素不保证有序。
默认使用对象的compareTo方法提供比较规则,如果你需要自定义比较规则则可以自定义comparators。
类图结构
由图可知,
PriorityBlockingQueue内部有一个数组queue,用来存放队列元素,size用来存放队列元素个数。
allocationSpinLock是个自旋锁,其使用CAS操作来保证同时只有一个线程可以扩容队列,状态为0或者1,其中0表示当前没有进行扩容,1表示当前正在扩容。
由于这是一个优先级队列,所以有一个比较器comparator用来比较元素大小。
lock独占锁对象用来控制同时只能有一个线程可以进行入队、出队操作。
notEmpty条件变量用来实现take方法阻塞模式。这里没有notFull 条件变量是因为这里的put操作是非阻塞的,为啥要设计为非阻塞的,是因为这是无界队列。
在如下构造函数中,默认队列容量为11,默认比较器为null,也就是使用元素的compareTo方法进行比较来确定元素的优先级,这意味着队列元素必须实现了Comparable接口。
/** * Default array capacity. */ private static final int DEFAULT_INITIAL_CAPACITY = 11; /** * Creates a {@code PriorityBlockingQueue} with the default * initial capacity (11) that orders its elements according to * their {@linkplain Comparable natural ordering}. */ public PriorityBlockingQueue() { this(DEFAULT_INITIAL_CAPACITY, null); } /** * Creates a {@code PriorityBlockingQueue} with the specified * initial capacity that orders its elements according to their * {@linkplain Comparable natural ordering}. * * @param initialCapacity the initial capacity for this priority queue * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ public PriorityBlockingQueue(int initialCapacity) { this(initialCapacity, null); } /** * Creates a {@code PriorityBlockingQueue} with the specified initial * capacity that orders its elements according to the specified * comparator. * * @param initialCapacity the initial capacity for this priority queue * @param comparator the comparator that will be used to order this * priority queue. If {@code null}, the {@linkplain Comparable * natural ordering} of the elements will be used. * @throws IllegalArgumentException if {@code initialCapacity} is less * than 1 */ public PriorityBlockingQueue(int initialCapacity, Comparator<? super E> comparator) { if (initialCapacity < 1) throw new IllegalArgumentException(); this.lock = new ReentrantLock(); this.notEmpty = lock.newCondition(); this.comparator = comparator; this.queue = new Object[initialCapacity]; }
小Demo
先搞个Demo体会PriorityBlockingQueue的使用方法。在这个Demo中,会把具有优先级的任务放入队列,然后从队列里面逐个获取优先级最高的任务来执行