ReentrantLock的公平性机制以牺牲吞吐量为代价换取调度确定性,带来更高线程排队唤醒开销、更多内存屏障与上下文切换,并丧失锁重入和缓存局部性优势,仅适用于存在明确饥饿风险的场景。

ReentrantLock 的公平性机制确实会带来可观的性能代价,核心在于它牺牲了部分吞吐量来换取确定性的调度顺序。
线程排队与唤醒开销显著增加
公平锁强制所有未获取到锁的线程立即进入 AQS 同步队列尾部,不再允许“插队”尝试。这意味着每次 lock() 调用失败后,必须执行完整的入队(addWaiter)、挂起(park)操作;而锁释放时,也必须严格唤醒队列头部线程,不能跳过等待者直接响应新请求。这个过程涉及多次 volatile 写、CAS 操作和线程状态切换,比非公平锁多出 2~3 倍的原子指令和上下文切换次数。
CPU 缓存与内存屏障压力上升
为保证队列顺序可见性,公平锁在入队、出队、唤醒等关键路径上插入更多内存屏障(如 full fence),强制刷新 CPU 缓存行。尤其在多核高争用场景下,频繁的 cache line 无效化(cache invalidation)会导致明显的总线争用,拖慢整体执行节奏。实测显示,在 32 核服务器上,当锁竞争强度超过每秒 10 万次时,公平锁的平均延迟比非公平锁高出约 40%~60%。
无法利用“锁重入”与“缓存局部性”优势
非公平锁允许刚释放锁的线程在下次调用 lock() 时大概率再次抢到锁(即所谓“自旋偏好”或“缓存亲和性”),这在单线程高频访问临界区时极为高效。而公平锁彻底屏蔽了这种优化:哪怕同一个线程刚释放锁,下一个请求也必须排队,失去本地 CPU 缓存热数据优势,同时增加不必要的调度延迟。
立即学习“Java免费学习笔记(深入)”;
适用场景有限,多数业务并不需要绝对公平
- 仅当存在明确饥饿风险(如定时任务线程长期被高优先级请求压制)时才需启用公平模式
- Web 请求处理、RPC 服务等典型场景中,请求天然具备随机性和短生命周期,非公平锁反而更贴近真实负载特征
- 若需控制资源分配权重,应优先考虑信号量(Semaphore)或自定义调度器,而非依赖锁的公平性



















