狂野飙车6鸿蒙版
471.84M · 2025-10-31
synchronized 关键字具备 可重入性(Reentrancy),同一线程在持有锁的情况下,可以再次获取同一把锁而不会阻塞。本文将从概念、代码示例、JVM 实现机制和工程实践四个方面,深入解析 synchronized 的可重入性。
可重入性(Reentrant)是指 同一线程在持有锁时,可以重复进入被同一个锁保护的临界区,而不会发生死锁。
换句话说:如果锁是“可重入”的,那么一个线程在进入某个 synchronized 方法/代码块后,还能继续调用另一个需要同一把锁的 synchronized 方法。
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,因为这是同一线程在请求同一把对象锁。
class Parent {
public synchronized void doSomething() {
System.out.println("父类方法执行");
}
}
class Child extends Parent {
@Override
public synchronized void doSomething() {
System.out.println("子类方法执行");
super.doSomething(); // 依然是同一把锁
}
}
结果:子类方法调用父类方法不会造成死锁,因为锁是可重入的。
在 JVM 中,synchronized 是基于 对象头中的 Monitor(监视器锁) 实现的。
Monitor 内部维护了一个 计数器(recursions) ,用于记录线程重入的次数。
这就是为什么 synchronized 能避免 同一线程自我阻塞 的根本原因。
methodA() 的时候进入 methodB() 就会死锁。synchronized。ReentrantLock 也支持可重入,并提供了更多功能(可中断、公平锁、条件队列)。synchronized。synchronized 的可重入性是并发编程中的重要特性:
理解可重入性,可以帮助我们在设计并发程序时写出更加 安全、简洁、易维护 的代码。