ReentrantLock实现原理摘记
ReentLock实现了Lock接口,内部定义了一个final 的抽象类 Sync 他继承了AQS,因此ReentLock的很多事情其实都是由Sync类做的,而sync类中的方法实现都要借助AQS.
Sync 有俩个子类,分别是公平锁类FairSync,和非公平锁 NonfairSync ,以下是非公平锁获取锁的流程:
如果cas失败,则直接尝试抢锁
如果抢锁失败,则将当前线程封装为,EXCLUSIVE节点,加入CLH队列,并且让当前线程阻塞,
tryAcquire实际调用的是NonfairSync锁的nonfairTryAcquire方法
以下为CLH队列初始化的方法,并加入第一个节点的方式
然后会再有一次入队排序操作
对于公平锁而言,实现大体与非公平过程类似,但是在一开始的抢锁的步骤略有不同
第一次经过addWaiter,需要通过enq方法,队列进行初始化
因为enq内部是死循环,初始化好之后,继续再执行一次,执行如下所示
然后调用acquireQueued方法,抢占失败后 然后进入shouldParkAfterFailedAcquire,进行waitStatus的改变,主要是为了标记当前节点后面还有节点再等待唤醒.
总结,非公平锁的lock方法实现,直接用cas修改状态,然后再尝试抢锁过程,而公平锁则直接调用抢锁过程,抢锁过程会调用tryAcquire方法,如果锁状态是0,即非占有,非公平锁不会管CLH队列的顺序直接进行cas,抢锁失败了才会加入CLH队列尾部,而公平锁,则会判断CLH队列是否为空,如果不会空,直接把自己加入队列尾部。