可重入锁(Reentrant Lock)是Java并发编程中常用的一种锁。可重入锁允许一个线程在持有锁的情况下再次获取同一个锁,以便在多层嵌套的代码块或方法调用中实现锁的续借。这有助于避免死锁和提高并发性能。
定义和特点
可重入锁是一种能够被重复加锁和解锁的锁,它允许线程在持有锁的情况下再次获取该锁,即使这个锁是同一个对象或类的不同实例。这使得在多层嵌套的代码块或方法调用中实现锁的续借成为可能。
代码示例
下面是一个简单的`ReentrantLock`示例,演示了如何在多层嵌套的方法调用中续借锁。
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private final ReentrantLock lock = new ReentrantLock();
private int value;
public void increment() {
lock.lock();
try {
// 执行加1操作
value++;
// 如果需要再次获取锁,可以调用lock()方法
increment(); // 续借锁
} finally {
lock.unlock();
}
}
public void decrement() {
lock.lock();
try {
// 执行减1操作
value--;
// 如果需要再次获取锁,可以调用lock()方法
decrement(); // 续借锁
} finally {
lock.unlock();
}
}
public int getValue() {
lock.lock();
try {
return value;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
ReentrantLockExample example = new ReentrantLockExample();
// 创建多个线程对计数器进行操作
new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
}).start();
new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.decrement();
}
}).start();
}
}
在上面的示例中,`increment()`和`decrement()`方法在执行过程中可能会调用自身来完成加1或减1的操作。由于`ReentrantLock`是可重入的,因此同一个线程可以在已经持有锁的情况下重复获取该锁而不会导致死锁。
可重入性的好处
可重入锁的主要好处包括:
- 避免死锁:当一个线程进入一个方法的内部并需要再次获取相同的锁时,可重入锁允许它这样做而不必担心死锁问题。
- 提高并发性能:在多层嵌套的方法调用中,可重入锁允许线程在不释放原有锁的情况下继续获得新的锁,从而减少了锁的竞争和持有时间。
- 简化代码设计:使用可重入锁可以使代码更加清晰简洁,因为不需要在每个方法中都显式地释放锁。