You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Doug Lea关于ArrayBlockingQueue与LinkedBlockingQueue表述的疑问求解

关于Doug Lea对ArrayBlockingQueue与LinkedBlockingQueue的表述答疑

问题1:Aren't allocating the things put into queues指代的具体场景

这句话核心指「放入队列的元素不需要临时分配内存」的场景,常见的有三类:

  • 元素是提前预分配好的对象池成员:比如提前初始化了一批任务对象,全程复用这些对象入队、消费后放回对象池,全程没有新对象创建
  • 放入队列的是全局常驻的静态对象、枚举值:比如用队列传递状态枚举、单例信号对象,这类对象JVM启动后就常驻内存,不会因为入队出队产生新分配
  • 队列传递的是基础类型包装类常量:比如Integer缓存范围内的数值、Boolean的TRUE/FALSE对象,这类对象也不需要临时分配内存

这种场景下,整个入队出队流程原本就没有新对象的创建销毁,LinkedBlockingQueue的Node节点每次入队分配新对象、出队后变成垃圾的额外开销就会凸显,原本可以忽略的GC影响会变成明显的性能损耗。

问题2:队列既非空也非满且无大量线程竞争时ArrayBlockingQueue更优的原因

要理解这个结论,首先得明确两个队列的核心实现差异:

ArrayBlockingQueue底层是固定长度的数组,入队出队只用移动游标,所有操作共用一把重入锁;出队元素后直接把对应数组位置置空,没有额外对象操作。
LinkedBlockingQueue底层是链表实现,为了提升并发度做了入队锁、出队锁分离,入队要新生成Node对象、赋值next指针,出队要把旧Node置空等待GC。

满足前提条件时,ArrayBlockingQueue的优势主要体现在三点:

  • 无锁分离的额外开销:因为没有大量竞争,LinkedBlockingQueue的双锁设计完全发挥不出优势,反而加锁解锁的次数、锁的内存屏障开销和ArrayBlockingQueue持平甚至更高
  • 内存局部性更好:数组是连续内存空间,CPU缓存命中率远高于链表的离散Node节点,存取元素的速度要快很多
  • 无额外对象开销:不需要创建/销毁Node对象,既省了分配对象的CPU开销,也没有Young GC的额外压力,整体吞吐量更稳定

如果不满足这个前提,比如队列经常处于空/满状态,线程需要频繁阻塞唤醒,或者并发量很高,LinkedBlockingQueue的双锁可以支持一边入队一边出队的并发操作,扩展性就会比单锁的ArrayBlockingQueue好很多。

内容的提问来源于stack exchange,提问作者woxihuanxiayua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 05:27:00