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。
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号