1.ReetrantLock是什么?
ReetrantLock是基于Lock接口实现的一种可重入锁,说到重入锁,其实synchronized也是一种可重入锁,
但是它与synchronized有本质的区别,ReetrantLock底层是依靠AQS来实现的,而Synchronized是基于monitor监视器来实现的;
ReetrantLock是有两种模式的,一种是公平锁模式,一种是非公平锁模式,其实就是获取锁的时候是否按照顺序获得。注:源码只分析非公平锁模式。
2.AQS在ReetrantLock中怎么使用的?
ReetrantLock并没有直接继承AQS这个抽象类,而是通过内部定义一个抽象Sync类来继承AQS,然后实现一部分通用的锁需要的方法比如tryRelease方法,然后再通过定义公平类和非公平类来继承这个抽象类Syn,然后实现具体的Lock方法,其实这里是用到了典型的模板方法模式,AQS中定义了加锁的整个算法执行逻辑结构,具体加锁实现留给子类去实现。
下面是它的AQS在ReetrantLock的实现类。
1 | java复制代码//ReetrantLock的全局AQS子类. |
3.ReetrantLock的Lock执行流程以及源码分析
上图是Lock的大概流程,下面是部分源码解读:
1 | java复制代码//1.第一步是调用ReetrantLock的lock方法 |
简单小结:首先线程尝试获取锁,如果失败,创建一个Node节点,该节点包含当前线程,然后添加到AQS的双向等待队列中,最后再一次进行尝试获取锁,如果失败,则准备挂起当前线程,但是挂起之前会把等待队列中已经被Signal唤醒的节点移除调用再添加到等待队列中,最后挂起。
4.ReetrantLock的unLock执行流程以及源码分析
上图是解锁的大概流程,下面看一些具体的源码解读:
1 | java复制代码第一步:先调用unlock |
小结: 解锁比较简单,就是判断是否是当前线程,如果是则通过cas修改state,并且判断是否是只重入了一次,如果是则已经释放锁成功,则唤醒队列后续可以唤醒的节点,否则不是重入,则锁持有者线程不变。
其他一些比如Condition条件分析,待续….
本文转载自: 掘金