PriorityBlockingQueue 的put方法底层源码

一、PriorityBlockingQueue 的put方法底层源码

PriorityBlockingQueue 的 put 方法用于将元素插入队列。由于 PriorityBlockingQueue 是一个无界队列,put 方法不会阻塞,总是会成功插入元素


1、put 方法的作用

  • 将元素插入队列。

  • 由于队列无界,put 方法不会阻塞,总是会成功插入元素。

  • 插入后,队列会根据元素的优先级重新排序。


2、put 方法的源码

以下是 PriorityBlockingQueue 中 put 方法的源码(基于 JDK 17):

可以看到,put 方法直接调用了 offer 方法。因此,我们需要进一步分析 offer 方法的实现。


3、offer 方法的源码

以下是 PriorityBlockingQueue 中 offer 方法的源码:


4、源码解析


(1)参数检查

  • PriorityBlockingQueue 不允许插入 null 元素,如果传入 null,会抛出 NullPointerException。


(2)获取锁

  • lock 是 PriorityBlockingQueue 的成员变量,用于控制插入和移除操作的并发访问。

  • 调用 lock() 方法获取锁。


(3)检查队列容量

  • size 是当前队列中的元素数量。

  • 如果队列已满(n >= queue.length),调用 grow() 方法扩容。

  • grow() 方法的实现:


(4)插入元素并调整堆结构

  • siftUp 方法将元素插入堆中,并调整堆结构以维持堆的性质:

siftUp 方法通过比较元素和其父节点,将元素插入到正确的位置,以维持堆的性质(最小堆或最大堆)


(5)更新队列大小

  • 将队列大小加 1。


(6)唤醒消费者线程

  • 如果队列之前为空,调用 notEmpty.signal() 唤醒可能正在等待的消费者线程。


(7)释放锁

  • 在 finally 块中释放锁,确保锁一定会被释放,避免死锁。


(8)返回结果

  • 由于队列无界,offer 方法总是返回 true。


二、关键点总结

  • 无界队列:PriorityBlockingQueue 是无界队列,put 方法不会阻塞。

  • 堆结构:使用堆数据结构维护元素的优先级顺序。

  • 线程安全:通过 ReentrantLock 保证线程安全。

  • 动态扩容:当队列容量不足时,会自动扩容。


三、示例流程图

以下是 put 方法的执行流程图:


1、检查元素是否为 null。


2、获取锁。


3、检查队列容量,如果不足则扩容。


4、将元素插入堆中,并调整堆结构。


5、更新队列大小。


6、如果队列之前为空,唤醒消费者线程。


7、释放锁。


8、返回 true。

posted @ 2025-02-19 21:32  jock_javaEE  阅读(20)  评论(0)    收藏  举报