LinkedBlockingQueue的poll方法底层原理

一、LinkedBlockingQueue的poll方法底层原理

LinkedBlockingQueue 的 poll 方法用于从队列头部移除并返回元素。如果队列为空,poll 方法会立即返回 null,而不会阻塞线程


1、poll 方法的作用

  • 从队列头部移除并返回元素。

  • 如果队列为空,立即返回 null。

  • 该方法是非阻塞的,适用于需要快速响应的场景。


2、poll 方法的源码

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


3、源码解析


(1)检查队列是否为空

  • count 是一个 AtomicInteger,表示当前队列中的元素数量。

  • 如果队列为空(count.get() == 0),立即返回 null。


(2)获取锁

  • takeLock 是 LinkedBlockingQueue 的成员变量,用于控制移除操作的并发访问。

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


(3)再次检查队列是否为空

  • 在加锁后再次检查队列是否为空,避免在加锁期间队列状态发生变化


(4)移除元素

  • 调用 dequeue 方法从队列头部移除节点并返回其元素。

  • dequeue 方法的实现:


(5)更新元素数量

  • 使用 AtomicInteger 的 getAndDecrement 方法将队列元素数量减 1,并返回减 1 之前的值(c)


(6)唤醒其他消费者线程

  • 如果移除后队列不为空(c > 1),调用 notEmpty.signal() 唤醒其他可能正在等待的消费者线程。


(7)释放锁

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


(8)唤醒生产者线程

  • 如果移除前队列已满(c == capacity),调用 signalNotFull() 唤醒可能正在等待的生产者线程。

  • signalNotFull() 的实现:


(9)返回移除的元素

  • 返回从队列头部移除的元素。


二、关键点总结

  • 非阻塞:如果队列为空,poll 方法会立即返回 null,而不会阻塞线程。

  • 锁分离:LinkedBlockingQueue 使用两把锁(putLock 和 takeLock),分别控制插入和移除操作,提高了并发性能。

  • 条件变量:使用 notFull 和 notEmpty 两个 Condition 实现线程的阻塞和唤醒。

  • 线程安全:通过锁和原子变量(AtomicInteger)保证线程安全。


三、与 take 方法的对比


四、示例代码

以下是一个简单的示例,展示 poll 方法的使用场景:

posted @ 2025-02-19 19:12  jock_javaEE  阅读(362)  评论(0)    收藏  举报