linkedblockingqueue 使用 atomicinteger 而非 int 是因它采用双锁机制(putlock 和 takelock),若用 int 则 size() 需同时获取两把锁,严重降低吞吐量;atomicinteger 基于 cas 实现 count 的原子增减与读取,避免竞态且无需锁协调。

LinkedBlockingQueue 中的 count 是一个 AtomicInteger 类型的变量,用于**原子地维护队列当前元素个数**,避免在多线程环境下因竞态条件导致计数错误。
为什么用 AtomicInteger 而不是 int?
因为 LinkedBlockingQueue 是线程安全的阻塞队列,多个线程可能同时执行 put()、take()、offer()、poll() 等操作。这些操作都会读取或修改元素数量:
-
put()成功后需count.incrementAndGet() -
take()成功后需count.decrementAndGet() -
size()方法直接返回count.get()
如果用普通 int,++ 或 -- 操作不是原子的(读-改-写三步),多线程下极易丢失更新。而 AtomicInteger 底层基于 CAS(Compare-and-Swap)指令,保证了这些操作的原子性与可见性。
count 在源码中如何被使用?
在 JDK 的 LinkedBlockingQueue 实现中(如 JDK 8+),count 定义为:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
关键操作示例:
- 入队(如
enqueue()内部):count.getAndIncrement()—— 先获取再加一,返回旧值 - 出队(如
dequeue()内部):count.getAndDecrement()—— 先获取再减一,返回旧值 - 判断是否为空:
count.get() == 0 - 判断是否满:
count.get() == capacity(注意:capacity 是 final 的)
注意:count 不代表“实时精确大小”的全部语义
虽然 count 是原子更新的,但它的值反映的是**最后一次成功入队/出队后的快照**。例如:
-
size()返回count.get(),是 O(1) 的,但不保证调用瞬间的绝对一致性(比如刚有一个线程进入put()但尚未完成 CAS,此时size()还没变) -
isEmpty()和isFull()都基于count,因此高效且线程安全 - 它不参与锁逻辑(队列用两个独立的
ReentrantLock控制 take/put),仅专注计数,职责单一
和 ArrayBlockingQueue 的计数方式对比
ArrayBlockingQueue 也用 AtomicInteger 维护 count,原理相同;区别在于:
- LinkedBlockingQueue 默认容量为
Integer.MAX_VALUE,所以isFull()很少为 true - ArrayBlockingQueue 使用数组 + 循环索引,
count同样靠 CAS 更新,但底层结构不同不影响计数器设计思想
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










