ReentrantLock 是如何实现公平锁的?ReentrantLock 是如何实现非公平锁的
时间: 2024-01-12 18:41:12 浏览: 84
ReentrantLock 类提供了公平锁和非公平锁两种模式,默认情况下是非公平锁。
在公平锁模式下,线程获取锁的顺序是按照请求锁的先后顺序进行的,即先请求的线程先获取锁。为了实现公平锁,ReentrantLock 内部维护了一个 FIFO 队列,所有请求锁的线程都会进入这个队列。当锁被释放时,队列中的第一个线程将会获得锁。
在非公平锁模式下,线程获取锁的顺序是不确定的,也就是说后请求的线程有可能先获取到锁。当一个线程请求非公平锁时,它会先尝试直接获取锁,如果获取失败,才会将自己加入等待队列中。如果锁被释放时,等待队列中有线程,那么队列中的第一个线程才会尝试获取锁。
在实现非公平锁时,ReentrantLock 采用了“CAS 自旋”技术,即线程会不断尝试获取锁,而不是直接进入等待队列。这可以减少线程进入等待队列的次数,从而提高锁的性能。但是由于非公平锁的获取顺序是不确定的,因此有可能会导致某些线程一直无法获取到锁,从而出现“饥饿”现象。
相关问题
java中什么是公平锁?什么是非公平锁?什么是可重入锁?
在Java中,公平锁是指多个线程按照申请锁的顺序来获取锁,即先申请锁的线程先获取锁,后申请的线程后获取锁。而非公平锁是指多个线程获取锁的顺序是不确定的,有可能后申请的线程先获取锁,这种情况下可能会导致线程饥饿。
可重入锁是指同一个线程可以重复获取同一把锁,而不会出现死锁的情况。在Java中,synchronized关键字和ReentrantLock类都是可重入锁。当一个线程已经获得了某个对象的锁,再次请求该对象锁时,如果该锁是可重入的,则请求成功,否则将会阻塞等待自己释放该对象的锁。可重入锁避免了死锁的情况,提高了代码的灵活性和可维护性。
ReentrantLock的优势是什么?
ReentrantLock是Java中的一个锁实现,相于传统的synchronized关键字,它具有以下优势[^1][^2]:
1. 可重入性:ReentrantLock允许同一个线程多次获取锁,而不会发生死锁。这对于一些复杂的线程交互场景非常有用。
2. 公平性:ReentrantLock可以选择公平锁或非公平锁。公平锁会按照线程请求锁的顺序来获取锁,而非公平锁则允许插队。这样可以避免某些线程长时间等待锁的情况,提高了整体的吞吐量。
3. 条件变量:ReentrantLock提供了Condition接口,可以通过它实现线程间的协调和通信。通过Condition,我们可以实现更加灵活的线程等待和唤醒机制。
4. 可中断性:ReentrantLock提供了可中断的获取锁的方式。当一个线程在等待锁的过程中,可以通过中断来取消等待,避免线程长时间阻塞。
5. 锁的细粒度控制:ReentrantLock允许我们通过lock()和unlock()方法手动控制锁的获取和释放,这样可以更加灵活地控制锁的粒度,提高代码的性能。
下面是一个使用ReentrantLock的示例代码:
```java
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo {
private static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Thread thread1 = new Thread(() -> {
lock.lock();
try {
// 执行线程1的任务
} finally {
lock.unlock();
}
});
Thread thread2 = new Thread(() -> {
lock.lock();
try {
// 执行线程2的任务
} finally {
lock.unlock();
}
});
thread1.start();
thread2.start();
}
}
```
阅读全文