synchronized天然支持重入,由jvm通过monitor自动实现:首次加锁设_owner为当前线程、_recursioncount为1;同一线程再次进入只增计数;计数归零才释放锁。

synchronized 在 Java 中天然支持重入,不需要额外配置或手动管理。它的重入能力是 JVM 内置机制直接保障的,核心在于每个锁对象都关联一个“持有线程 ID”和“重入计数器”。
重入的基本表现
同一个线程在已持有某对象锁的前提下,再次进入该对象的其他 synchronized 方法或同步块时,不会被阻塞,而是直接通行。
- 方法调用链中嵌套同步方法:如 methodA()(synchronized)内部调用 methodB()(也是 synchronized),且两者锁目标一致(比如都是 this)
- 同步块之间嵌套:多个 synchronized(lock) { ... } 块使用同一个 lock 对象,同一线程可连续进入
- 父子类间调用:子类 synchronized 方法调用父类的 synchronized 方法,共享同一对象锁
JVM 是如何实现重入的
关键靠对象头中的锁状态字段与计数器协同工作:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 首次获取锁时,JVM 记录当前线程 ID,并将重入计数器设为 1
- 同一线程再次请求同一把锁,计数器加 1(不是重新抢锁,也不更新线程 ID)
- 每次退出同步范围(方法结束或同步块执行完),计数器减 1
- 只有当计数器归零时,锁才真正释放,其他线程才有机会竞争
重入带来的实际好处
它让同步逻辑更自然、更安全,避免了人为设计锁嵌套时的死锁风险:
- 支持递归调用:比如同步方法内部调用自身(需控制终止条件)
- 简化组合逻辑:一个业务方法加锁后,可放心调用其他受同一锁保护的工具方法
- 继承场景下保持一致性:子类复用父类同步行为时,无需担心锁冲突
注意边界情况
重入只对“同一把锁”生效,不同锁对象之间不互通:
- 如果 methodA 锁的是 this,methodB 锁的是 new Object(),那不算重入,会正常竞争
- 静态 synchronized 方法锁的是 Class 对象,与实例方法锁的 this 不是同一把锁,也不构成重入
- ReentrantLock 也支持重入,但它是显式 lock()/unlock(),而 synchronized 是隐式、自动管理的
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










