ArrayBlockingQueue 的公平性由构造时 fair 参数决定,本质是 ReentrantLock 是否启用公平策略,仅影响线程争锁顺序而不改变队列 FIFO 逻辑;fair=true 时按 FIFO 唤醒等待最久的线程,避免饥饿但吞吐较低,适用于实时或保序场景。

ArrayBlockingQueue 的公平性,本质是通过构造时传入的 fair 参数,决定其内部使用的 ReentrantLock 是否启用公平策略。它不改变队列逻辑,只影响线程争夺锁的调度顺序。
公平锁如何影响线程排队行为
当 fair = true 时,ReentrantLock 会维护一个等待线程的 FIFO 队列。线程在尝试获取锁失败后,会被加入到这个等待队列尾部;一旦锁释放,仅队首线程能被唤醒并尝试获取锁。这确保了“先到先得”——等待时间最长的线程优先获得访问权。
而默认的非公平模式(fair = false)允许新来的线程直接与刚被唤醒的线程竞争锁,可能造成“插队”,导致部分线程长期得不到执行(即饥饿),但吞吐量通常更高。
公平性对存取操作的实际表现
公平性不会改变 ArrayBlockingQueue 的 FIFO 数据顺序(元素仍是先进先出),但它决定了哪条线程能**最先执行** put() 或 take() 操作:
- 生产者线程调用 put():若队列已满,线程阻塞在 notFull 条件上;锁释放后,公平模式下等待最久的生产者优先被唤醒并重试插入。
- 消费者线程调用 take():若队列为空,线程阻塞在 notEmpty 条件上;锁释放后,公平模式下等待最久的消费者最先被通知并执行出队。
- 注意:条件等待(await)本身也受锁公平性约束——signal() 唤醒的是等待队列中最靠前的线程,而非随机唤醒。
何时该启用公平模式
公平性不是“更好”的代名词,而是权衡选择:
- 适用场景:对响应时间敏感、需避免个别线程长期饥饿的系统,如实时任务分发、金融交易中的请求保序处理。
- 慎用场景:高吞吐、低延迟要求的系统(如日志收集、消息中转),非公平锁减少线程唤醒/切换开销,性能更优。
- 实测提示:在锁争抢不激烈时(例如线程数少、队列容量大),公平与非公平差异微乎其微;只有在高并发+频繁阻塞时,公平性带来的调度开销才明显可测。
关键细节:公平性只作用于锁,不作用于条件变量本身
需要明确的是:notFull 和 notEmpty 是 ReentrantLock 关联的 Condition 实例,它们的 await/signal 行为完全依赖底层锁的公平策略。也就是说,公平性不是 ArrayBlockingQueue 自己实现的排队逻辑,而是委托给 ReentrantLock 的标准机制。因此,你无需额外编码控制顺序——只要构造时指定 fair=true,整个阻塞-唤醒链路就自动具备公平语义。










