首页 > Java > java教程 > 正文

java ArrayBlockingQueue源码探讨

冷炫風刃
发布: 2025-12-05 16:50:03
原创
378人浏览过
ArrayBlockingQueue 是基于单锁双条件变量的有界循环数组队列,线程安全、不支持 null、容量固定;使用 takeIndex/putIndex 实现无取模环形写入,公平性仅影响锁获取顺序。

java arrayblockingqueue源码探讨

ArrayBlockingQueue 是 Java 并发包中一个经典、高效的有界阻塞队列,底层基于数组 + 可重入锁(ReentrantLock)+ 条件变量(Condition)实现。它线程安全、支持公平/非公平策略、不支持 null 元素,且容量固定不可扩容。

核心结构:数组 + 两把锁?不,是一把锁 + 两个条件

很多人误以为 ArrayBlockingQueue 用“双锁”(putLock / takeLock)像 LinkedBlockingQueue 那样分离读写,其实不是——它只用一个 final ReentrantLock lock,但定义了两个 Condition:

  • notFull:供 put() 等待“队列未满”;
  • notEmpty:供 take() 等等待“队列非空”。

所有入队(offer/put/add)、出队(poll/take/remove)、查看(peek)操作,都必须先获取 lock。这是它吞吐量略低于 LinkedBlockingQueue(双锁)的原因,但也换来更少内存开销和更简单的状态一致性控制。

环形数组怎么玩?靠 head/tail 指针 + 取模?不,是隐式取模

它内部是一个定长数组 final Object[] elements,但没有显式维护 head/tail 下标变量。而是用两个 int 成员:

立即学习Java免费学习笔记(深入)”;

Convai Technologies Inc.
Convai Technologies Inc.

对话式 AI API,用于设计游戏和支持端到端的语音交互

Convai Technologies Inc. 87
查看详情 Convai Technologies Inc.
  • takeIndex:下一个 take() 将读取的位置(即队头索引);
  • putIndex:下一个 put() 将写入的位置(即队尾索引)。

入队时:elements[putIndex] = x; putIndex = (++putIndex == elements.length) ? 0 : putIndex;
出队时:Object x = elements[takeIndex]; elements[takeIndex] = null; takeIndex = (++takeIndex == elements.length) ? 0 : takeIndex;
这就是典型的“循环数组”手动翻转逻辑,避免了每次取模运算(%),性能更稳。

公平性怎么体现?只在锁上做文章

构造函数可传 boolean fair 参数:

  • fair = true:创建的是 new ReentrantLock(true),线程按等待顺序获取锁(FIFO);
  • fair = false(默认):非公平锁,允许插队,吞吐更高,但可能饥饿。

注意:公平性只影响锁的获取顺序,不影响队列本身的 FIFO 行为——ArrayBlockingQueue 始终严格保序,因为所有操作串行化在一把锁下。

几个关键细节你可能忽略

  • null 不被允许:put(null) 直接抛 NullPointerException,避免后续判空歧义;
  • 批量操作不保证原子性:addAll() 是循环调用 add(),中途失败会部分成功(已加的回不去);
  • size() 和 isEmpty() 是 O(1):它缓存了 count 字段,每次增减都更新,不遍历数组;
  • iterator() 返回的迭代器是弱一致性的:不抛 ConcurrentModificationException,但可能漏掉刚加入或跳过已移除元素。

基本上就这些。源码不到 800 行,逻辑清晰,是理解 Java 显式锁与条件变量协作的绝佳入口。

以上就是java ArrayBlockingQueue源码探讨的详细内容,更多请关注php中文网其它相关文章!

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号