reentrantlock在低竞争场景下性能接近synchronized但开销略高,因其固定aqs流程无锁降级或自旋优化;synchronized可启用偏向锁实现近乎零开销,而reentrantlock每次调用仍需cas、节点操作等。

ReentrantLock 在短时间锁竞争(即低竞争)场景下,性能表现接近 synchronized,但开销略高,主要源于其固定路径的 AQS 机制——它不进行锁降级或自旋优化,每次调用 lock()/unlock() 都需执行完整流程。
低竞争下的实际行为特征
当并发线程数少(如 1–4 线程)、临界区执行极快(纳秒级)、锁持有时间短时,竞争极少发生。此时:
- synchronized 可能启用偏向锁,后续加锁仅做一次线程 ID 比较,几乎零开销;
- ReentrantLock 仍需 CAS 更新 state、创建/回收 AQS 节点、检查中断状态,哪怕无竞争也保持稳定开销;
- 实测显示:2 线程争同一把非公平 ReentrantLock,吞吐量与 synchronized 相差通常在 ±3% 内,差异不具统计显著性。
影响性能的关键细节
短时间竞争不等于“无开销”,以下因素会放大 ReentrantLock 的相对成本:
-
未关闭偏向锁:JDK 15 前默认开启,会使 synchronized 在单线程反复加锁时明显占优;压测前建议加
-XX:-UseBiasedLocking; - 未预热 JIT:初期方法未被编译,CAS 和队列操作解释执行慢,首秒数据不可信;需至少 5 秒稳定运行后再采样;
-
临界区过短:若临界区本身只含几条赋值语句(如
count++),锁管理开销占比反而上升,此时 synchronized 更合适。
何时仍可选 ReentrantLock
即使竞争短暂,若业务需要以下能力,ReentrantLock 的“额外开销”是合理代价:
- 需响应中断(
lockInterruptibly()),例如任务取消或超时控制; - 需尝试获取锁避免阻塞(
tryLock()),如缓存穿透防护中的快速失败; - 需绑定多个条件变量(
newCondition()),实现精细唤醒逻辑。
快速判断是否属于短时间竞争
可用简化公式估算竞争强度:
竞争系数 ≈ (并发线程数 × 锁持有纳秒数) ÷ (临界区执行纳秒数 + 1)
结果 20,则已进入中高竞争区间,ReentrantLock 的可控性优势开始显现。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











