1.什么是ReentrantLock?
ReentrantLock基于AQS,在并发编程中可以实现公平锁和非公平锁来对资源进行同步,同时,和synchronized一样,ReentrantLock支持可重入,ReentrantLock在调度上更灵活,支持更多丰富的功能。
2.Lock接口
ReentrantLock实现了lock接口,则它必然具有lock所具有的抽象意义,而在lock的源码注释里,lock的意义在于提供了区别于synchronized的另一种具有更多广泛操作的同步方式,它能支持更多灵活的结构,并且可以关联多个Condition对象
注:Condition对象表示一个等待状态,获得锁的线程可能在某些时刻需要等待一些条件的完成才能继续执行,通过await方法注册在condition对象上进行等待,再通过condition对象的signal方法将其唤醒,类似于Object的wait和notify方法,并且一个Lock对象可以关联多个Condition,多个线程可以被绑定再不同的Condition对象上达到分组唤醒,Condition还提供限时、中断等功能,丰富线程调度策略
Lock源码中一共定义了6个方法:
public interface Lock {
void lock(); //获取锁,如果当前锁被其他线程占有那么将会等待直到获取为止
void lockInterruptibly() throws InterruptedException; //获取锁,但当线程在等待锁的过程中被中断则会退出等待并且抛出中断异常
boolean tryLock(); //尝试获取锁并立即返回布尔类型代表是否获取到锁
boolean tryLock(long time, TimeUnit unit) throws InterruptedException; //在一段时间内尝试获取锁,加入期间被中断则抛出中断异常
void unlock(); //释放锁
@NotNull Condition newCondition(); //新建一个绑定在当前Lock上的Condition对象
}
3.ReentrantLock的实现
ReentrantLock直译为“可重入的锁”,但是该工具本身除了可重入还支持其他许多特性
public class ReentrantLock implements Lock, java.io.Serializable {
private static final long serialVersionUID = 7373984872572414699L;
/** Synchronizer providing all implementation mechanics */
private final Sync sync;
/**
* Base of synchronization control for this lock. Subclassed
* into fair and nonfair versions below. Uses AQS state to
* represent the number of holds on the lock.
*/
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
/**
* Sync object for non-fair locks
*/
static final class NonfairSync extends Sync {
...}
/**
* Sync object for fair locks
*/
static final class FairSync extends Sync {
...}
ReentrantLock只有一个属性Sync并且修饰为final,意味着一旦初始化就不可修改引用了,另外RenntrantLock内部有三个核心的内部类,Sync、NonfairSync、FairSync,再就是对Lock接口的实现,其余的一些私有方法基本上都是为了方便开发者来获取一些状态值
Sync源码:
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -517952376203402586