非公平锁吞吐量更高,因其跳过公平锁的hasqueuedpredecessors()检查,直接cas抢锁,避免volatile读、缓存竞争、park/unpark及上下文切换,仅在抢失败时才排队。

非公平锁吞吐量更高,核心在于它跳过了公平锁中那个关键的队列前置检查——hasQueuedPredecessors(),直接用 CAS 尝试抢锁,把“能立刻拿锁”的路径压到最短。
抢锁路径更短:不查队列,先试再排
非公平锁的 lock() 一上来就执行 compareAndSetState(0, 1)。只要锁空闲(state == 0),新线程当场拿到锁,不入队、不挂起、不唤醒,全程在用户态完成。
公平锁则必须先调用 hasQueuedPredecessors():
– 判断队列是否为空,或自己是否排在队首;
– 这个判断要读 volatile 的 head/tail 节点,触发内存屏障和缓存同步;
– 即使队列为空,也得走完链表探查逻辑,无法跳过。
避免高频 volatile 读与缓存竞争
hasQueuedPredecessors() 在高并发下是隐形瓶颈:
– 每次调用至少两次 volatile 读(state + head);
– 多线程反复读同一 volatile 地址,引发 CPU 缓存行失效和总线争用;
– NUMA 架构下跨节点访问延迟更明显。
非公平锁在抢中时只做一次 volatile 写(CAS 修改 state),完全绕开队列结构访问,减少内存压力。
Java Linux版下载入口,提供 Oracle JDK 26.0.2 官方 Linux 安装包、Java 环境配置、JDBC 数据库连接和 Java 服务端开发相关信息。
省掉 park/unpark 和上下文切换
公平锁要求每个新请求线程都走完整等待流程:
– 创建 Node 实例;
– CAS 更新 tail 指针;
– 设置前驱 waitStatus;
– 调用 LockSupport.park() 进入 WAITING 状态。
这些操作带来真实开销: – 用户态到内核态切换(微秒至毫秒级); – 频繁对象分配加重 GC 压力; – 唤醒依赖链表遍历,可能跳过 CANCELLED 节点。
非公平锁在锁释放瞬间被新线程抢中,整个过程无阻塞、无调度介入,延迟压缩到纳秒级。
不是永远不排队,而是“抢不过才排”
非公平锁的“插队”只发生在锁空闲的瞬时窗口期: – 抢失败后,依然走标准 AQS 流程:addWaiter → acquireQueued → park; – 一旦入队,后续唤醒仍是 FIFO,不破坏队列内部顺序; – 饥饿只出现在极端场景:临界区极短 + 新线程持续高频抵达。
实际业务中,只要临界区超过几十纳秒,队列中的线程基本都能获得执行机会。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










