Java synchronized
同步锁深度全解
——从对象头到锁升级、性能调优与并发设计
一、实现原理:对象头、Monitor 与 JVM 源码级分析
1. 对象头(Object Header)与 Mark Word 的底层结构
Java 对象的存储布局由三部分组成:
- 对象头(Header):包含 Mark Word(锁状态、哈希码等)和类型指针(指向类的元数据)。
- 实例数据(Instance Data):对象实际字段内容。
- 对齐填充(Padding):保证对象起始地址为 8 字节的整数倍。
Mark Word 的详细结构(64 位 JVM)
锁状态 | 存储内容(64 位) | 锁标志位 |
---|---|---|
无锁 | 哈希码(31b) + 分代年龄(4b) + 未使用(1b) | 001 |
偏向锁 | 线程ID(54b) + Epoch(2b) + 分代年龄(4b) | 101 |
轻量级锁 | 指向栈帧中锁记录的指针(62b) | 00 |
重量级锁 | 指向 Monitor 的指针(62b) | 10 |
GC 标记 | 未使用(用于 GC 阶段) | 11 |
注:32 位 JVM 的 Mark Word 结构类似,但字段长度按比例缩短。
2. Monitor 机制的 JVM 源码实现
每个 Java 对象在进入重量级锁状态时,其 Mark Word 指向一个 ObjectMonitor 对象(HotSpot 源码):
// hotspot/src/share/vm/runtime/objectMonitor.hpp
class ObjectMonitor {
volatile markOop _header; // 原始对象头的备份
void* _owner; // 持有锁的线程(NativeThread)
volatile intptr_t _count; // 可重入次数
volatile intptr_t _waiters; // 等待线程数
ObjectWaiter* _EntryList; // 竞争锁失败的线程队列
ObjectWaiter* _WaitSet; // 调用 wait() 的线程队列
// ... 其他字段省略