您的位置: 首页> Java源码> synchronized 的可重入性:避免死锁的隐藏武器

synchronized 的可重入性:避免死锁的隐藏武器

时间:2025-09-09 14:30:02 来源:互联网

摘要

synchronized 关键字具备 可重入性(Reentrancy),同一线程在持有锁的情况下,可以再次获取同一把锁而不会阻塞。本文将从概念、代码示例、JVM 实现机制和工程实践四个方面,深入解析 synchronized 的可重入性。


正文

一、什么是可重入性?

可重入性(Reentrant)是指 同一线程在持有锁时,可以重复进入被同一个锁保护的临界区,而不会发生死锁。

换句话说:如果锁是“可重入”的,那么一个线程在进入某个 synchronized 方法/代码块后,还能继续调用另一个需要同一把锁的 synchronized 方法。


二、代码示例

1. 方法递归调用
public class ReentrantDemo {
    public synchronized void methodA() {
        System.out.println(Thread.currentThread().getName() + " 进入 methodA");
        methodB(); // 再次请求同一个锁
    }

    public synchronized void methodB() {
        System.out.println(Thread.currentThread().getName() + " 进入 methodB");
    }

    public static void main(String[] args) {
        ReentrantDemo demo = new ReentrantDemo();
        new Thread(demo::methodA, "T1").start();
    }
}

结果:线程 T1 先进入 methodA,随后 不会阻塞,而是直接进入 methodB,因为这是同一线程在请求同一把对象锁。

2. 父子类继承中的可重入性
class Parent {
    public synchronized void doSomething() {
        System.out.println("父类方法执行");
    }
}

class Child extends Parent {
    @Override
    public synchronized void doSomething() {
        System.out.println("子类方法执行");
        super.doSomething(); // 依然是同一把锁
    }
}

结果:子类方法调用父类方法不会造成死锁,因为锁是可重入的。


三、JVM 如何实现可重入性?

在 JVM 中,synchronized 是基于 对象头中的 Monitor(监视器锁) 实现的。
Monitor 内部维护了一个 计数器(recursions) ,用于记录线程重入的次数。

这就是为什么 synchronized 能避免 同一线程自我阻塞 的根本原因。


四、可重入性的优势

  1. 避免死锁
  1. 提升编程灵活性
  1. 降低锁使用的复杂度

五、工程实践建议

  1. 理解可重入,但不要滥用
  1. 注意递归调用的深度
  1. 对比 ReentrantLock

六、总结

synchronized 的可重入性是并发编程中的重要特性:

理解可重入性,可以帮助我们在设计并发程序时写出更加 安全、简洁、易维护 的代码。

上一篇:你的图片又被别人“白嫖”了?用这篇Java防盗链攻略说再见! 下一篇:Java Stream reduce方法深度解析

相关文章

相关应用

最近更新