Java ReentrantLock深度解析:原理与实战
4 浏览量
更新于2024-08-28
收藏 181KB PDF 举报
"带你看看Java的锁(一)-ReentrantLock"
本文主要探讨Java中的ReentrantLock,这是一种可重入的互斥锁,属于Java并发包java.util.concurrent.locks中的核心类。ReentrantLock提供了比内置的synchronized关键字更高级、更灵活的锁定机制。
**ReentrantLock简介**
ReentrantLock,顾名思义,"重入"表示一个线程已经获得了锁,如果它尝试再次获取该锁,锁的状态会允许它继续。这与synchronized不同,synchronized在尝试获取已被其持有的锁时会抛出死锁异常。ReentrantLock通过AQS(AbstractQueuedSynchronizer)内部的state字段来跟踪锁的持有状态。
**Synchronized对比**
ReentrantLock和synchronized都是用于控制多线程对共享资源的访问,但ReentrantLock提供了更多特性。synchronized由JVM直接实现,而ReentrantLock由JDK提供,因此ReentrantLock更具有扩展性。它可以显式地获取和释放锁,支持公平锁和非公平锁策略,具备尝试获取锁的超时功能,以及线程中断处理机制。然而,使用ReentrantLock时,开发者需要确保在finally块中正确释放锁,以防止资源泄漏。
**公平锁与非公平锁**
ReentrantLock可以通过构造函数选择公平锁或非公平锁。公平锁保证按照线程等待队列的顺序分配锁,而非公平锁则不保证这一顺序,可能会有更高的吞吐量,但可能导致饥饿现象。
**构造函数**
ReentrantLock的构造函数允许指定公平策略:
```java
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
```
默认情况下,ReentrantLock是非公平的。
**lock()方法**
- `lock()`:非公平锁的加锁方法,尝试立即获取锁,如果失败则会被放入等待队列。
- `lockInterruptibly()`:与`lock()`类似,但在等待获取锁时能够响应中断,如果线程被中断,将会抛出InterruptedException。
- `tryLock()`:尝试获取锁,如果当前没有其他线程持有锁,立即返回true;否则,返回false,不会阻塞。
- `tryLock(long time, TimeUnit unit)`:尝试在指定时间内获取锁,如果在规定时间内获取成功,返回true,否则返回false,并可能在等待期间响应中断。
**unlock()方法**
释放锁,调用`unlock()`方法将减少持有锁的线程计数。如果计数为0,则释放锁,并唤醒等待队列中的下一个线程。
**Condition**
ReentrantLock还支持多个条件变量,每个条件变量都有自己的等待队列。通过`newCondition()`方法可以创建新的Condition实例,这样线程可以在满足特定条件时等待,而其他线程可以通知它们。
**总结**
ReentrantLock提供了比synchronized更丰富的功能,包括可选择的公平策略、显式锁获取和释放、支持中断和超时、以及多条件等待。然而,使用ReentrantLock需要更多的编程工作,因为它没有synchronized的自动管理能力。根据应用场景,开发者可以选择更适合的同步机制。
2020-08-18 上传
2022-07-10 上传
2020-12-21 上传
2021-05-19 上传
2020-12-11 上传
2020-12-21 上传
2021-06-04 上传
2021-05-25 上传
2022-06-12 上传
weixin_38745859
- 粉丝: 3
- 资源: 969