【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
操作尝试获取锁。 - 重量级锁:如果轻量级锁竞争激烈,则进一步升级为重量级锁,依赖操作系统内部的互斥锁。
- 偏斜锁(
- 锁升级过程:
- 无竞争时使用偏斜锁。
- 有其他线程尝试获取锁时,偏斜锁撤销并