非公平锁性能更高,因其省去排队前的状态检查、避免Node对象创建与线程挂起,仅通过一次CAS抢占锁;公平锁则需多次volatile读、CAS及完整入队流程,开销显著增大。

非公平锁省去了排队前的多次状态检查
非公平锁在 lock() 和 tryAcquire() 两个入口处,都会直接执行 compareAndSetState(0, 1) 尝试抢占。只要此时锁空闲(state == 0),就立即成功,完全不查同步队列是否为空、也不管有没有线程正在排队。这意味着: - 刚释放锁的瞬间,新来的线程大概率“捡漏”成功,根本不会走到入队逻辑 - 即使队列里已有多个等待节点,它仍可穿插获取,跳过整个排队链路
避免高频 volatile 读和 CAS 开销
公平锁必须调用 hasQueuedPredecessors() 来判断是否该排队。这个方法要: - 读取 head 和 head.next 的引用(volatile 读) - 检查 next 节点的 waitStatus 是否为 CANCELLED - 若是,还要继续向后遍历找第一个有效节点 每一步都涉及内存屏障和可能的缓存失效,高竞争下开销迅速放大。而非公平锁绕开了全部这些操作,一次 CAS 就完成判断与获取。
不创建 Node 对象,也不触发线程挂起
非公平锁抢锁成功时: - 完全不新建 Node 实例,节省堆内存分配和 GC 压力 - 不更新 tail 指针(无需 CAS tail) - 不设置前驱节点的 waitStatus = SIGNAL - 更不会调用 LockSupport.park() 进入阻塞态 而公平锁一旦排队失败,就要走完整套 addWaiter → enq → acquireQueued 流程,每步都含对象分配、volatile 写、CAS 和潜在的内核态切换。
减少用户态与内核态切换次数
线程挂起(park)和唤醒(unpark)涉及从用户态陷入内核态,代价很高。公平锁强制排队,导致更多线程进入 WAITING/BLOCKED 状态;而非公平锁让部分线程在锁释放的“窗口期”直接执行,显著降低 park/unpark 频次。尤其在临界区很短的场景下,一个线程可能抢到锁、执行完、释放锁,全程都不触发任何线程调度干预。


















