一、synchronized 的锁升级
JDK 6 后 synchronized 不再是重量级锁,而是按竞争程度锁升级:无锁 → 偏向锁 → 轻量级锁 → 重量级锁,只升不降。
| 阶段 | 适用 | 机制 |
|---|---|---|
| 偏向锁 | 单线程访问 | 标记线程 ID,免 CAS |
| 轻量级锁 | 竞争不激烈 | CAS 自旋抢锁 |
| 重量级锁 | 竞争激烈 | monitor,线程阻塞(OS 互斥) |
二、为什么引入
早期 synchronized 直接挂 monitor,线程阻塞涉及用户态/内核态切换,慢。锁升级让”无竞争/低竞争”场景几乎零成本,只有真抢才膨胀到重量级。
三、与 ReentrantLock 对比
- synchronized:JVM 内置、自动释放、优化好,一般够用;
- ReentrantLock:可中断、公平锁、多条件 Condition,灵活但需手动 unlock;
- 高竞争且需高级功能时选后者,否则前者更简洁。
注意:偏向锁在 JDK 15 后默认关闭(撤销成本高),多数场景轻量级锁已足够。