fair=true会降低吞吐量15%–30%,因其启用reentrantlock公平模式,强制fifo排队、维护clh队列并限制插队,增加volatile写和cas开销;非公平模式通过允许插队减少上下文切换与缓存失效,提升吞吐,适用于日志写入等场景;仅当需保序、实时响应或确证线程饥饿时才应启用。

fair 参数设为 true 会明显降低吞吐量,实测通常下降 15%–30%,尤其在高并发、短耗时任务场景下更显著。
公平锁如何拖慢速度
开启 fair=true 后,ArrayBlockingQueue 内部使用 ReentrantLock(true),强制线程按 FIFO 顺序排队争锁。每次 put/take 都要:
- 维护 CLH 等待队列节点(新增 volatile 写和 CAS 操作)
- 唤醒时只放行队首线程,不能“插队”
- 锁释放后需遍历等待队列查找下一个可唤醒者
这些额外开销在每微秒级操作中累积,导致整体吞吐下降。
非公平模式为何更快
默认 fair=false 时,新线程可能直接抢到刚释放的锁,跳过等待队列。虽然可能造成个别线程饥饿,但省去了队列管理成本:
- 无须维护等待节点顺序
- 锁获取路径更短,CAS 失败概率更低
- 更适合批量日志写入、后台批处理等吞吐优先场景
什么时候值得用 fair=true
不是为了“看起来更公平”,而是解决具体问题:
- 实时告警通道:要求最早阻塞的请求最先被响应
- 保序强依赖场景:如金融订单处理,需严格按提交时间消费
- 调试或压测中发现明显线程饥饿(某线程长期 wait 不被唤醒)
注意:peek()、size() 等非阻塞方法不受 fair 影响,始终无锁执行。
别误判性能下降原因
看到吞吐掉下来,别急着怀疑队列容量或 GC——先确认是否开启了 fair=true。很多团队在切换 fair 模式后没做压测对比,就把性能问题归因于其他环节。
建议上线前用相同负载对比 fair=true/false 的 QPS 和 p99 延迟,再决策。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











