Java随笔-锁
2026/8/6 17:54:32 网站建设 项目流程

Java 中的锁可以从多个维度分类,但核心演进脉络集中在 synchronized从 "纯重量级锁"到"锁升级体系"的优化,以及 JUC 显式锁体系的成熟。下面按分类、演进、原理三层展开。

一、Java 锁的宏观分类

1. 按实现层面

类型代表控制方
隐式锁synchronizedJVM 自动管理(进入/退出 monitorenter/monitorexit)
显式锁ReentrantLockReadWriteLock程序员手动lock()/unlock()

2. 按竞争策略

类型思想代表
悲观锁先加锁,再操作synchronizedReentrantLock
乐观锁先操作,提交时 CAS 检查AtomicIntegerLongAdder

3. 按特性

  • 公平/非公平:是否按请求顺序分配锁
  • 可重入/不可重入:同一线程能否多次获取同一把锁
  • 共享/独占:读锁共享、写锁独占
  • 自旋/阻塞:竞争时 CPU 空转等待 vs 线程挂起

4. 按状态(synchronized 核心)

演进的主线:无锁 → 偏向锁 → 轻量级锁 → 重量级锁

二、锁的演进史:synchronized 的四代优化

1. JDK 1.0 ~ 1.5:纯重量级锁(性能黑洞)

早期 synchronized 直接调用操作系统mutex(互斥量)

  • 线程阻塞 = 用户态 → 内核态切换
  • 线程唤醒 = 内核态 → 用户态切换
  • 即使单线程反复进入,也要走完整内核流程

当时 Java 并发性能被严重诟病,直到 Doug Lea 推出 JUC(java.util.concurrent) 包,用 ReentrantLock + CAS 绕过 JVM 锁。

2. JDK 1.6:锁升级体系(JVM 团队反击)

JVM 团队发现:大多数锁不仅不存在多线程竞争,而且总是由同一线程多次获得。于是引入 锁升级(Lock Coarsening/Elimination 之外的核心优化)

① 无锁(Lock-Free)
  • 对象初始状态,或显式使用 Atomic 类
  • 依赖 CPU 的 cmpxchg(CAS)指令
  • Mark Word 标志:…| age:4 | biased_lock:0 | lock:01
② 偏向锁(Biased Locking)
  • 场景:只有一个线程访问同步块
  • 原理:第一次获取锁时,用 CAS 把线程 ID 写入对象头的 Mark Word。之后该线程进入同步块,只需检查 Mark Word 里的线程 ID 是否是自己,无需任何原子操作。
  • 撤销成本:一旦有第二个线程尝试获取,必须在安全点(STW)撤销偏向锁,这个代价不小。
  • 现状:JDK 15 废弃(JEP 374),JDK 18 默认关闭。现代硬件上收益变小,撤销成本反而成为负担。
③ 轻量级锁(Lightweight Locking)
  • 场景:多线程交替执行(竞争不激烈,没有同时抢)
  • 原理:线程在自己的栈帧中创建 Lock Record,然后用 CAS 把对象头的 Mark Word 替换为指向该 Lock Record 的指针。
    • 成功:获得锁
    • 失败:自旋(默认 10 次,JDK 1.6 后引入自适应自旋:根据历史成功率动态调整次数)
  • 优点:线程不阻塞,避免内核态切换
  • 缺点:自旋消耗 CPU,竞争激烈时自旋就是浪费
④ 重量级锁(Heavyweight Locking)
  • 场景:竞争激烈,自旋失败
  • 原理:锁膨胀(inflate)为 Monitor(ObjectMonitor)
    • 对象头 Mark Word 指向 ObjectMonitor 地址
    • 未获得锁的线程进入 _EntryList 阻塞
    • 持有锁的线程执行完后,从 _EntryList 唤醒一个竞争线程
  • 开销:内核态切换,但适合长时间持有锁的场景

3. JDK 1.6 另外两项编译优化

优化原理效果
锁消除(Lock Elimination)逃逸分析发现锁对象不会被其他线程访问,直接去掉同步局部变量StringBuffer的同步常被消除
锁粗化(Lock Coarsening)相邻的同步块合并为一个更大的同步块减少反复加锁/解锁开销

三、Mark Word 结构:锁状态的载体

对象头中的Mark Word是锁状态的存储载体。以64 位 JVM为例:

锁状态62 bitsbiased_lock (1 bit)lock (2 bits)
无锁unused:25 + hash:31 + unused:1 + age:4001
偏向锁thread:54 + epoch:2 + unused:1 + age:41101
轻量级锁ptr_to_lock_record:62-00
重量级锁ptr_to_monitor:62-10
GC 标记ptr_to_cms_promoted_obj:62-11

lock 字段(2 bits)+ biased_lock 字段(1 bit)共同标识当前锁状态。

四、锁升级完整流程图

对象创建 │ ▼ ┌─────────────┐ │ 无锁状态 │◄────────────────────────┐ │ (匿名可偏向) │ │ └──────┬──────┘ │ │ │ ▼ │ 线程A尝试获取 │ │ │ ▼ │ ┌─────────────┐ 线程A再次进入 │ │ 偏向锁状态 │◄──────────────────┐ │ │ Mark Word记录 │ │ │ │ 线程A ID │ │ │ └──────┬──────┘ │ │ │ │ │ ▼ 线程B尝试获取 │ │ 检查epoch/撤销 │ │ │ │ │ ▼ │ │ ┌─────────────┐ │ │ │ 轻量级锁 │ CAS成功 │ │ │ 自旋竞争 │───────────────────┘ │ └──────┬──────┘ │ │ │ ▼ 自旋失败/竞争激烈 │ 锁膨胀(inflate) │ │ │ ▼ │ ┌─────────────┐ 锁释放后 │ │ 重量级锁 │────────────────────────┘ │ ObjectMonitor│ └─────────────┘

关键规则

  • 锁升级是单向的:偏向锁 → 轻量级锁 → 重量级锁,不能降级
  • 重量级锁释放后,对象回到无锁状态,下次竞争重新走升级流程
  • 偏向锁撤销后,可能直接升级为轻量级锁,也可能先回到无锁

五、显式锁体系:JUC 的补足

synchronized 的升级体系是 JVM 自动优化的,但灵活性不足。JUC 提供了更精细的控制:

1. ReentrantLock(基于 AQS)

ReentrantLocklock=newReentrantLock(true);// true=公平锁lock.lock();try{// 临界区}finally{lock.unlock();}
  • 底层是 AQS(AbstractQueuedSynchronizer),通过 volatile int state + CAS + 双向链表管理队列
  • 支持公平/非公平、可中断(lockInterruptibly)、超时(tryLock(timeout))、多条件变量(Condition)

2. ReadWriteLock

  • 读锁:共享锁,多个线程可同时读
  • 写锁:独占锁,写时阻塞读写
  • 适合读多写少场景

3. StampedLock(JDK 8)

  • 引入乐观读锁:先读,提交时验证版本号,未被写则成功,被写了再升级为悲观读
  • 性能比 ReadWriteLock 更高,但使用复杂

六、对比总结

维度synchronizedReentrantLockCAS(无锁)
实现层JVM(字节码monitorenterAPI(AQS)CPU 指令
锁升级✅ 支持(偏向→轻量→重量)❌ 直接 AQS 队列无锁,无升级
公平性非公平可选公平/非公平-
可中断❌ 不支持lockInterruptibly-
条件队列1 个(wait/notify多个Condition-
性能JDK 1.6 后接近 ReentrantLock略优(极端竞争)无竞争时最优
使用难度低(自动释放)高(需finally unlock高(ABA 问题)

七、演进时间线

版本锁相关演进
JDK 1.0synchronized纯重量级锁,性能差
JDK 1.2引入Lock接口雏形,但 synchronized 未优化
JDK 1.5JUC 包正式发布(ReentrantLockAtomicAQS
JDK 1.6锁升级(偏向/轻量/重量)、锁消除、锁粗化、自适应自旋
JDK 1.7G1 GC,继续优化同步性能
JDK 1.8引入StampedLockLongAdder(分段 CAS)
JDK 15废弃偏向锁(JEP 374),现代并发模型下收益为负
JDK 18默认关闭偏向锁,未来可能彻底移除

八、总结

Java 锁的演进本质是"能不动内核就不动内核":从早期直接调用操作系统 mutex(重量级),到发现大多数锁无竞争后引入偏向锁(零开销)、轻量级锁(CAS 自旋),再到 JUC 用 AQS 把排队逻辑搬到用户态。最终趋势是偏向锁被淘汰,轻量级锁 + CAS + AQS成为主流。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询