【Java面试笔记:进阶】16.synchronized底层如何实现?什么是锁的升级、降级?
在 Java 中,synchronized 关键字的底层实现依赖于 对象头(Object Header) 和 监视器锁(Monitor) 机制,并通过 锁的状态升级(Lock Escalation) 来优化同步性能。
1. synchronized 的底层实现
synchronized 的同步机制基于 Monitor 对象,它是同步的基本实现单元。
通过 monitorenter 和 monitorexit 指令实现同步逻辑。
1. 对象头与 Mark Word
-
1.对象头结构:
每个 Java 对象在内存中由三部分组成:Mark Word(标记字段):存储对象自身的运行时数据(如哈希码、锁状态等)。Klass Pointer(类型指针):指向类的元数据信息。- 数组长度(仅数组对象有)。
-
2.Mark Word 内容:
Mark Word的长度为 32/64 位(取决于 JVM 位数),其内容根据锁状态动态变化:锁状态 存储内容 无锁 对象哈希码、分代年龄等 偏向锁 持有偏向锁的线程 ID、偏向时间戳 轻量级锁 指向栈中锁记录(Lock Record)的指针 重量级锁 指向监视器(Monitor)的指针
2. 监视器锁(Monitor)
-
1.Monitor 结构:
每个对象关联一个Monitor,其核心字段包括:Owner:持有锁的线程。EntryList:等待获取锁的阻塞线程队列。WaitSet:调用wait()后进入等待状态的线程队列。
-
2.锁的获取流程:
- 线程进入
synchronized代码块时,尝试通过CAS操作修改Mark Word。 - 若成功,则获取锁;若失败,则根据锁状态进行 锁膨胀(升级为更高等级的锁)。
- 线程进入
2. 锁的升级与降级
- 锁的三种状态:
- 偏斜锁(
Biased Locking):默认情况下,当没有竞争时使用。通过CAS操作在对象头的Mark Word部分设置线程ID,表示对象偏向当前线程。 - 轻量级锁:当有其他线程尝试获取锁时,偏斜锁会撤销并升级为轻量级锁。轻量级锁依赖
CAS操作尝试获取锁。 - 重量级锁:如果轻量级锁竞争激烈,则进一步升级为重量级锁,依赖操作系统内部的互斥锁。
- 偏斜锁(
- 锁升级过程:
- 无竞争时使用偏斜锁。
- 有其他线程尝试获取锁时,偏斜锁撤销并
