HoRain云--synchronized 底层原理全解析——从对象头到 Monitor
synchronized 是 Java 并发编程中最基础的同步机制,本文从 JVM 对象内存布局出发,深入剖析 Mark Word 的结构、monitorenter/monitorexit 字节码指令以及 Monitor 对象的底层实现,结合 Java 17 的 JOL 工具展示对象头的实际变化。
标签:Java synchronized 对象头 Monitor JVM
目录
-
为什么需要 synchronized
-
Java 对象内存布局
-
Mark Word 详解
-
Monitor 对象原理
-
monitorenter / monitorexit 字节码分析
-
Java 17 实战:用 JOL 观察对象头
-
常见坑
-
面试题
-
总结
-
参考资料
1. 为什么需要 synchronized
在多线程环境下,多个线程同时访问共享资源会导致数据不一致。synchronized 关键字通过互斥锁机制保证同一时刻只有一个线程能进入临界区,从而保证线程安全。
2. Java 对象内存布局
Java 对象在内存中分为三块区域:对象头、实例数据和对齐填充-2。对象头包含 Mark Word 和 Klass Pointer 两部分。
3. Mark Word 详解
Mark Word 是对象头的核心部分,64 位 JVM 中占 8 字节。其结构随锁状态动态变化:
| 锁状态 | 存储内容 | 标志位 |
|---|---|---|
| 无锁 | 哈希码(25bit) + 分代年龄(4bit) | 01 |
| 偏向锁 | 线程ID(23bit) + Epoch(2bit) + 分代年龄 | 01 |
| 轻量级锁 | 指向栈中锁记录的指针 | 00 |
| 重量级锁 | 指向 Monitor 的指针 | 10 |
| GC标记 | 空 | 11 |
4. Monitor 对象原理
Monitor 是 synchronized 重量级锁的实现基础,由 C++ 的 ObjectMonitor 实现,包含 Owner、EntryList、WaitSet 等关键字段。当线程获取锁失败时,会进入 EntryList 阻塞等待。
5. monitorenter / monitorexit 字节码分析
同步代码块编译后会生成 monitorenter 和 monitorexit 指令-。同步方法则通过 ACC_SYNCHRONIZED 标志实现。
6. Java 17 实战代码
java
复制
下载
import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;
public class ObjectHeaderDemo {
private static final Object lock = new Object();
public static void main(String[] args) throws InterruptedException {
System.out.println("JVM: " + VM.current().details());
System.out.println("=== 无锁状态 ===");
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
synchronized (lock) {
System.out.println("=== 持有锁状态 ===");
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
System.out.println("=== 释放锁后 ===");
System.out.println(ClassLayout.parseInstance(lock).toPrintable());
}
}
7. 常见坑
-
误认为 synchronized 锁的是代码块而非对象
-
混淆对象锁与类锁的作用范围:对象锁只锁当前实例,类锁锁整个类
-
在方法上使用 synchronized 等同于对整个方法体加锁,粒度可能过大
8. 面试题
Q1:synchronized 锁的是什么? 锁的是对象。同步代码块锁括号中的对象,同步方法锁当前实例(this),静态同步方法锁 Class 对象。
Q2:Monitor 的 Owner 字段有什么作用? 记录当前持有锁的线程,实现可重入性的关键。
Q3:为什么说 synchronized 早期性能差? 早期 synchronized 直接依赖操作系统的 Mutex,线程竞争时立即进入内核态阻塞,上下文切换开销大-61。
9. 总结
synchronized 通过对象头中的 Mark Word 和 Monitor 对象实现线程同步。理解对象头结构是掌握锁升级的前提,也是理解 JVM 并发优化的基础。
更多推荐

所有评论(0)