synchronized 同步代码块在字节码中通过 monitorenter 和 monitorexit 指令实现锁的获取与释放,前者尝试获取 monitor,后者确保正常和异常路径下均释放锁,jvm 保证二者成对且计数匹配。

Java 中 synchronized 同步代码块在字节码层面是通过 monitorenter 和 monitorexit 两条指令来控制的。
这两条指令直接操作对象关联的 Monitor(监视器),实现锁的获取与释放。
-
monitorenter:线程执行到该指令时,尝试获取指定对象的 Monitor 所有权。- 若 Monitor 未被占用,线程直接获得锁,锁计数器设为 1;
- 若已被其他线程持有,当前线程阻塞,直到 Monitor 可用。
-
monitorexit:用于释放 Monitor。编译器会插入两个位置的monitorexit:
Alibabacloud Sdk Client Initialization For Java下载在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 一个在同步块正常结束处;
- 另一个在异常处理表中(对应
catch或finally逻辑),确保即使抛出异常,锁也能被释放,避免死锁。
例如,以下 Java 代码:
public void doSync() {
synchronized(lock) {
System.out.println("hello");
}
}
编译后字节码中会出现类似结构:
6: monitorenter // 获取 lock 对象的 Monitor ... 16: monitorexit // 正常退出 22: monitorexit // 异常路径退出(保证锁释放)
JVM 保证这两个指令成对出现,且 monitorexit 的执行次数必须与 monitorenter 相等(可重入时计数匹配),否则会抛出 IllegalMonitorStateException。
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










