在Java中,可重入锁(ReentrantLock)和重入锁(Reentrant)是同一个概念,它们描述的是同一种锁的特性。因此,从定义上来说,可重入锁和重入锁没有区别。可重入锁(ReentrantLock)是Java中的一个类,属于java.util.concurrent.locks包,而重入锁(Reentrant)则是java.util.concurrent包中ReentrantLock类的一个特性。
可重入锁(ReentrantLock)的特性:
可重入性:一个线程可以多次获取同一个锁而不会导致死锁。这意味着,如果一个线程已经持有了某个可重入锁,它可以再次获取该锁而不会被阻塞。
公平性:可重入锁可以是公平的,也可以是非公平的。公平锁会按照线程请求锁的顺序来分配锁,而非公平锁则不保证这一点。
可中断性:与内置锁不同,可重入锁支持中断,这意味着在等待获取锁的过程中,线程可以被中断。
条件支持:可重入锁支持条件变量,允许线程在锁被持有时等待某个条件成立。
使用场景:
需要细粒度控制锁的场景:与内置锁(如synchronized)相比,可重入锁提供了更灵活的锁控制,可以在需要时精确地获取和释放锁。
需要实现更复杂的同步逻辑:可重入锁支持条件变量,允许实现更复杂的同步逻辑,如生产者-消费者模式等。
需要公平或非公平锁的场景:根据应用的需求,可以选择使用公平锁或非公平锁。
需要支持中断的场景:如果线程在等待获取锁的过程中需要响应中断,那么可重入锁是一个合适的选择。
示例代码:
下面是一个使用可重入锁(ReentrantLock)的简单示例:
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private final ReentrantLock lock = new ReentrantLock();
public void doSomething() {
lock.lock(); // 获取锁
try {
// 访问共享资源
System.out.println("Doing something...");
doSomethingElse(); // 再次获取同一个锁
} finally {
lock.unlock(); // 释放锁
}
}
private void doSomethingElse() {
lock.lock(); // 再次获取同一个锁
try {
// 访问共享资源
System.out.println("Doing something else...");
} finally {
lock.unlock(); // 释放锁
}
}
public static void main(String[] args) {
ReentrantLockExample example = new ReentrantLockExample();
example.doSomething();
}
}
在这个示例中,doSomething方法首先获取锁,然后调用doSomethingElse方法。doSomethingElse方法也尝试获取同一个锁。由于这是一个可重入锁,因此doSomethingElse方法能够成功获取锁,而不会导致死锁。最后,在doSomething方法的finally块中释放锁。