synchronized 的可重入性由 jvm 通过 monitor 自动实现,核心是识别持有线程并记录重入次数:_owner 存线程 id,_recursioncount 记次数,同一线程多次进入只增计数,退出时递减,归零才释放锁。

synchronized 的可重入性不是靠程序员写代码实现的,而是 JVM 在底层通过 Monitor(监视器)自动完成的。核心就两点:识别是不是自己、记录加了几次锁。
Monitor 是 synchronized 的“大脑”
每个 Java 对象背后都关联一个 Monitor 结构,它像一把智能锁,内部有三个关键字段:
- _Owner:存当前持有锁的线程 ID(初始为 null)
- _RecursionCount:记录该线程对这把锁的重入次数(初始为 0)
- _EntryList:存放正在排队等锁的其他线程
加锁过程:同一线程进来,计数加一
当线程执行 synchronized 方法或代码块时,JVM 会检查对应对象的 Monitor:
- 第一次进来:_Owner 为空 → 把当前线程设为 _Owner,_RecursionCount 设为 1
- 再次进来(比如递归调用或嵌套同步块):发现 _Owner 就是自己 → 不阻塞,直接 _RecursionCount + 1
解锁过程:只减次数,不放锁,直到归零
每次退出同步范围(方法结束或代码块结束),JVM 都会做一件事:
- 将 _RecursionCount 减 1
- 只有当 _RecursionCount 变成 0 时,才把 _Owner 清空,真正释放锁
- 中间任何一次减完还大于 0,锁依然被该线程牢牢占着
一个典型例子帮你理解
下面这段代码能顺利执行,不会卡死,正是因为可重入:
public synchronized void a() {System.out.println("进入 a");
b(); // 再次请求同一把锁
}
public synchronized void b() {
System.out.println("进入 b");
}
线程调用 a() 时拿到锁(_Count = 1);执行到 b() 时发现还是自己,直接 _Count 变成 2;等 b() 返回,_Count 减为 1;等 a() 返回,_Count 才减为 0,锁才真正释放。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











