java synchronized天然支持方法级重入,关键在于锁对象一致:实例方法锁this、静态方法锁class,jvm通过线程关联计数器实现重入,计数归零才释放锁,需避免锁对象不一致或逃逸。

Java隐式锁(即 synchronized)天然支持方法级重入同步,无需额外配置或手动管理,关键在于理解其锁对象归属和重入机制——它不是“能不能”,而是“怎么用才对”。
明确锁对象:this、Class 或自定义对象
方法是否可重入,取决于锁对象是否一致:
- 实例同步方法(
public synchronized void m())锁的是当前实例this;同一对象内嵌套调用其他synchronized实例方法,自动重入 - 静态同步方法(
public static synchronized void m())锁的是该类的Class对象;多个静态方法间相互调用也支持重入,但与实例方法互不干扰 - 若需跨实例或细粒度控制,建议显式使用
synchronized(obj)块并复用同一obj,避免误锁不同对象导致重入失效
利用JVM自动维护的重入计数器
synchronized 的重入不是“跳过检查”,而是由JVM在底层维护一个线程关联的计数器:
- 首次进入同步区域,计数器置为1,线程获得锁
- 同一线程再次进入同一锁对象的同步区域,计数器+1
- 每次退出同步区域(方法返回或块结束),计数器-1
- 仅当计数器归零时,锁才真正释放,其他线程才可竞争
这意味着递归调用、AOP代理嵌套、或工具类中复用同步方法,只要锁对象不变,就不会死锁。
避免常见陷阱:锁对象不一致或意外逃逸
看似是“方法级”,实则失效的典型场景:
- 在同步方法中 new 出新对象并对其加锁(如
synchronized(new Object())),每次都是新锁,无法重入 - 将
this作为参数传递给其他对象,并在其内部做synchronized(this)—— 若该对象被多处引用,可能引入外部锁竞争,破坏重入语义 - 子类重写同步方法但未声明
synchronized,父类调用时仍走父类锁,但子类实现无锁,逻辑割裂
配合设计提升可读性与可维护性
隐式锁虽简单,但优雅体现在结构清晰:
- 优先使用同步方法而非同步块,当整个方法逻辑需原子性时,语义更直白
- 若方法内仅部分代码需同步,且涉及多个共享对象,改用
synchronized(指定锁对象)块,并将锁对象声明为final成员变量 - 在文档或命名中体现意图,例如
updateBalanceAndLog()比doWork()更易判断是否应保持同步一致性
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











