Reentrant基础的内容就不再赘述,大家自行搜素下即可。
非公平锁
ReetrantLock中的非公平锁语义是什么?
涉及到锁竞争,就涉及如何竞争锁,以及竞争失败的处理,和锁释放后如何唤醒那些竞争失败的线程。
ReentrantLock的非公平锁实现中,在线程尝试获取锁时,会先尝试通过CAS获取锁,如果失败则会将当前线程加入等待队列尾部,并且根据条件将当前线程挂起。
在释放锁时,会将当前节点的next节点置为head节点,并唤醒next节点的线程。被唤醒线程会通过自旋尝试获取锁,但这里要注意的是,可能会出现与其他刚刚进来的线程竞争的情况,导致当前线程获取锁失败。 因此这里非公平锁的语义就是最先进入的请求无法保障能在锁资源释放后肯定能获取到锁,但等待队列中的线程还是能够保障先后顺序的。
获取锁的原理
● 获取锁失败首先进行自旋;
● 当达到指定条件后进入WATING状态;
● 当等待队列中的前一个线程释放锁之后,当前线程被唤醒,尝试获取锁,有可能会获取锁失败,被新进来的线程抢占;
● 获取锁失败就继续自旋,一直到获取锁成功。
● 获取锁时如果发现持有锁的是当前线程,会进行锁计数加一操作,这就是重入的逻辑。
释放锁的实现原理(公平、非公平锁相同)
公平锁
知道了非公平锁的语义是无法确保等待时间最常的头节点的线程立即获取到锁,那公平锁的语义就是保证线程获取锁的先后顺序。
与非公平锁实现的差别
公平锁与非公平锁的区别主要在tryAcquire
获取锁的实现中,非公平锁无论是否有等待的线程都尝试去获取锁,而公平锁每次都要判断队列中是否有线程等待,如果有线程的话就不获取锁。
详细的流程如下: