synchronized 的可重入性由 JVM 通过 Monitor 的 _owner 和 _count 字段实现:首次加锁设 _owner 为当前线程、_count 为 1;重入时仅递增 _count;仅当 _count 减至 0 才清空 _owner 并释放锁。

synchronized 是 Java 中内置的可重入锁实现,不需要手动加锁/解锁,由 JVM 在字节码层面自动管理。它的可重入性不是靠额外的数据结构(比如 ReentrantLock 里的 AQS),而是基于每个对象关联的监视器(Monitor)和一个计数器(Entry Count)来实现的。
可重入的核心:锁计数器 + 持有线程标识
每个 Java 对象都有一个与之关联的 Monitor(在 HotSpot 中对应 ObjectMonitor 结构)。Monitor 内部包含:
- _owner:记录当前持有锁的线程(仅一个线程能成为 owner)
- _count(或叫 entry count):记录该线程获取锁的次数,初始为 0
当一个线程第一次进入 synchronized 块时,JVM 将 _owner 设为该线程,_count 置为 1;再次进入同一把锁(比如递归调用、或嵌套 synchronized 方法),_count 自增;每次退出 synchronized 块,_count 减 1;只有当 _count 减到 0 时,才真正释放锁,_owner 清空。
典型可重入场景示例
以下代码不会死锁,正是依赖这个计数机制:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
public synchronized void methodA() {
methodB(); // 再次进入本对象的 synchronized 方法
}
public synchronized void methodB() {
// 执行逻辑
}
执行过程:
- 线程 T 进入 methodA → _owner = T,_count = 1
- T 调用 methodB → 同一把锁(this),发现 _owner 已是 T,直接 _count++(变为 2)
- methodB 返回 → _count--(变为 1)
- methodA 返回 → _count--(变为 0),锁释放
注意:可重入是「线程级」和「对象级」的
synchronized 的可重入只在同一对象、同一线程下生效:
- 不同对象的 synchronized 方法 → 互不影响(两把独立锁)
- 同一个对象,但不同线程 → 会阻塞等待(因为 _owner 不匹配)
- 静态 synchronized 方法 → 锁的是 Class 对象,不是实例,所以和实例方法不共享锁
和 ReentrantLock 的区别简要对比
虽然都可重入,但实现机制不同:
- synchronized:JVM 层原生支持,基于 Monitor 计数器,不可中断、不支持超时、无公平性选项,但更轻量、JIT 优化好(偏向锁、轻量级锁等)
- ReentrantLock:API 层实现,基于 AQS + state 计数器 + exclusiveOwnerThread 字段,功能更灵活(可中断、可超时、可公平),但需手动 lock/unlock

















