BlockingQueue---PriorityBlockingQueue
总结
一个无界的并发队列。
FIFO;
按照元素的优先级顺序来处理元素。这种队列非常适合需要按照优先级处理任务的场景。
特性
- 无界:默认情况下是无界的,可以存储任意数量的元素。
- 基于优先级:队列中的元素根据它们的自然顺序或者由构造时提供的
Comparator
来排序。 - 线程安全:支持多线程同时进行插入和移除操作。
- 非阻塞:插入操作不会被阻塞,即使队列中已经有很多元素;但是取元素的操作可能会被阻塞,如果队列为空。
构造函数
PriorityBlockingQueue()
: 创建一个默认初始容量为11的PriorityBlockingQueue
。PriorityBlockingQueue(int initialCapacity)
: 创建一个具有指定初始容量的PriorityBlockingQueue
。PriorityBlockingQueue(int initialCapacity, Comparator<? super E> comparator)
: 创建一个具有指定初始容量并使用指定比较器的PriorityBlockingQueue
。PriorityBlockingQueue(Collection<? extends E> c)
: 用给定集合中的元素初始化队列。PriorityBlockingQueue(PriorityBlockingQueue<? extends E> c)
: 用另一个PriorityBlockingQueue
初始化当前队列。PriorityBlockingQueue(SortedSet<? extends E> c)
: 用给定有序集合中的元素初始化队列。
方法
-
插入操作:
put(E e)
: 将指定的元素插入此优先级队列中。这个方法实际上等同于offer(E e)
,因为PriorityBlockingQueue
是无界的。offer(E e)
: 将指定的元素插入此优先级队列中。由于队列是无界的,所以总是会成功添加元素。
-
移除操作:
take()
: 检索并移除此队列的头(最高优先级),如果队列为空,则等待有元素可用。poll()
: 检索并移除此队列的头(最高优先级),如果队列为空,则立即返回null
。poll(long timeout, TimeUnit unit)
: 检索并移除此队列的头(最高优先级),如果队列为空,则最多等待指定的时间,如果超时队列仍然为空则返回null
。
-
检查操作:
peek()
: 检索但不移除此队列的头(最高优先级);如果队列为空,则返回null
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | public class PriorityBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable { private static final int DEFAULT_INITIAL_CAPACITY = 11; private transient Object[] queue; private transient int size; private transient Comparator<? super E> comparator; private final ReentrantLock lock ; public PriorityBlockingQueue() { this (DEFAULT_INITIAL_CAPACITY, null ); } public PriorityBlockingQueue( int initialCapacity) { this (initialCapacity, null ); } 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]; } // 插入指定元素到优先级队列 public boolean offer(E e) { if (e == null ) throw new NullPointerException(); final ReentrantLock lock = this . lock ; lock . lock (); int n, cap; Object[] array; while ((n = size) >= (cap = (array = queue).length)) tryGrow(array, cap); try { Comparator<? super E> cmp = comparator; if (cmp == null ) // siftUpComparable(n, e, array); else siftUpUsingComparator(n, e, array, cmp); size = n + 1; notEmpty.signal(); } finally { lock .unlock(); } return true ; } public E poll() { final ReentrantLock lock = this . lock ; lock . lock (); try { return dequeue(); } finally { lock .unlock(); } } private E dequeue() { int n = size - 1; if (n < 0) return null ; else { Object[] array = queue; E result = (E) array[0]; E x = (E) array[n]; array[n] = null ; Comparator<? super E> cmp = comparator; if (cmp == null ) siftDownComparable(0, x, array, n); else siftDownUsingComparator(0, x, array, n, cmp); size = n; return result; } } } |
示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | public static void main(String[] args) throws InterruptedException { // 创建一个PriorityBlockingQueue,使用自定义的降序比较器 PriorityBlockingQueue<Integer> queue = new PriorityBlockingQueue<>(10, (a, b) -> b - a); // 降序 // 生产者线程 Thread producer = new Thread(() -> { try { for ( int i = 0; i < 10; i++) { queue.put(i); System. out .println( "Produced: " + i); } } catch (Exception e) { Thread.currentThread().interrupt(); } }); producer.start(); Thread.sleep(1000); // 消费者线程 Thread consumer = new Thread(() -> { try { while ( true ) { Integer element = queue.take(); System. out .println( "Consumed: " + element); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }); consumer.start(); // 结果: // Produced: 0 //Produced: 1 //Produced: 2 //Produced: 3 //Produced: 4 //Produced: 5 //Produced: 6 //Produced: 7 //Produced: 8 //Produced: 9 //Consumed: 9 //Consumed: 8 //Consumed: 7 //Consumed: 6 //Consumed: 5 //Consumed: 4 //Consumed: 3 //Consumed: 2 //Consumed: 1 //Consumed: 0 } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)