可重入锁是一种支持同一个线程多次获得同一把锁的锁机制。在 Java 中,synchronized
关键字和 ReentrantLock
类都支持可重入锁。
可重入锁的主要特点是允许同一个线程多次获取同一把锁,而不会导致死锁。这使得在进行递归调用或者多层调用的情况下,线程可以自由地获取已经持有的锁。
示例:
1. 使用 synchronized 关键字
public class ReentrantExample {
public synchronized void outer() {
inner();
}
public synchronized void inner() {
// 这里可以访问 outer() 持有的锁
}
}
2. 使用 ReentrantLock 类
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantExample {
private final Lock lock = new ReentrantLock();
public void outer() {
lock.lock();
try {
inner();
} finally {
lock.unlock();
}
}
public void inner() {
lock.lock();
try {
// 这里可以访问 outer() 持有的锁
} finally {
lock.unlock();
}
}
}
在上述示例中,ReentrantExample
类中的 outer()
方法和 inner()
方法都使用了同一把锁(要么是 synchronized
锁,要么是 ReentrantLock
)。在 outer()
方法中调用了 inner()
方法,由于是同一线程,所以能够成功获取锁,不会产生死锁。
可重入锁的实现机制通常是通过给每个锁关联一个持有锁的线程和计数器。线程首次获得锁时,计数器设为1,每次重入锁时,计数器递增。只有当计数器归零时,锁才会完全释放。这样,同一个线程在多次重入锁后,只有在最后一次释放锁时,其他线程才能获得该锁。这种机制确保了可重入性和避免了死锁的发生。