0.是什么
ReentrantLock
是 java.util.concurrent.locks
包中的一个类,提供了比 synchronized
关键字更灵活和强大的锁机制。
ReentrantLock
实现了 Lock
接口,它允许显式地加锁和解锁,并提供了一些高级功能,如中断锁请求、超时锁请求、公平锁和非公平锁选择等。
1.为什么
在Java诞生之初,就有了synchronized
,ReentrantLock
是在 JDK 1.5 中引入的,为啥要引入这个呢?
引入 ReentrantLock
的主要原因是为了解决 synchronized
关键字的一些局限性,并提供更灵活和强大的锁机制,以应对复杂的并发编程需求。
1.1 synchronized的缺点
序号 | 局限性 | 描述 |
---|---|---|
1 | 锁的细粒度控制 | synchronized 是隐式锁定的,无法显式地控制锁的获取和释放,锁的范围是整个方法或代码块。 |
2 | 不可中断的锁获取 | 线程在等待获取 synchronized 锁时,不能被中断,可能导致长时间等待,无法响应中断请求。 |
3 | 无法实现公平锁 | synchronized 锁是非公平的,不能保证锁的获取顺序,可能导致某些线程长时间得不到锁,造成“饥饿”现象。 |
4 | 缺乏条件变量支持 | synchronized 只提供了 wait() 、notify() 和 notifyAll() 方法进行线程间的协调,但这些方法的使用和控制相对简单,无法实现复杂的等待条件。 |
1.2 ReentrantLock的优点
序号 | 优势 | 描述 |
---|---|---|
1 | 显式锁定和解锁 | 需要显式调用 lock() 获取锁,并显式调用 unlock() 释放锁,提供了对锁的细粒度控制。 |
2 | 可中断锁获取 | 支持 lockInterruptibly() 方法,在等待锁的过程中可以响应中断。 |
3 | 超时锁获取 | 支持 tryLock(long timeout, TimeUnit unit) 方法,允许在指定时间内尝试获取锁,如果超时则放弃获取。 |
4 | 公平锁和非公平锁 | 可以选择公平锁(按请求顺序获取锁)和非公平锁(可能会插队获取锁)。 |
5 | 条件变量支持 | 提供 newCondition() 方法,可以创建多个 Condition 对象,实现复杂的线程间协调。 |
6 | 查询锁状态 | 提供方法查询锁的状态,如 isLocked() 判断锁是否被任何线程持有,isHeldByCurrentThread() 判断锁是否被当前线程持有。 |