synchronized 是可重入锁,避免同一线程因重复获取同一把锁而自我阻塞;其通过锁对象内的递归计数器实现,首次加锁设为1并记录线程ID,重入时计数器递增,归零才释放锁。

Java 中的 synchronized 是可重入锁,意思是同一个线程在已经持有某把锁的前提下,可以再次获取这把锁而不会被自己阻塞。
可重入解决什么问题
避免“自己锁死自己”。比如一个同步方法内部调用另一个同步方法,且两者锁的是同一个对象:
- 如果锁不可重入,线程进入第一个方法时拿到锁,调用第二个方法时又要申请同一把锁,就会因无法获取而无限等待——实际就是死锁。
- 而
synchronized允许重入,所以能正常执行下去,业务逻辑不被底层锁机制打断。
底层靠计数器实现重入
每个锁对象(如 monitor)内部维护一个递归计数器(recursion count):
- 线程第一次获取锁时,计数器设为 1,同时记录持有者线程 ID。
- 同一线程再次进入,计数器 +1;每次退出同步块或方法,计数器 -1。
- 只有计数器减到 0 时,锁才真正释放,其他线程才有机会竞争。
重入发生在哪些场景
只要锁对象相同,以下情况都属于重入:
立即学习“Java免费学习笔记(深入)”;
- 同步实例方法调用本类另一个同步实例方法(锁对象是
this)。 - 同步静态方法调用本类另一个同步静态方法(锁对象是
Class对象)。 - synchronized 代码块嵌套另一个以相同对象为锁的 synchronized 代码块。
- 递归调用中反复进入加了
synchronized的方法。
和不可重入锁对比更直观
想象一把老式机械门锁:
- 不可重入:进门一次就落锁,再想进卧室还得先出门、重新掏钥匙、再开一次——但人还在玄关里,出不去,卡住了。
- 可重入:门锁认得你,进门后不用反复解锁,直接推卧室门就行;离开时统一锁一次门。


















