显式锁之ReentrantLock实现

2021/12/25 23:12:49

本文主要是介绍显式锁之ReentrantLock实现,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

  下图是Lock接口清单,定义了一些抽象的锁操作。Java本身提供了内部锁机制,那么还需要显示Lock,何用?与内部加锁机制不同,Lock提供了无条件、可轮询、定时、可中断的锁获取操作;所有加锁和解锁的操作都是显式的。既然是锁,那么Lock的实现必须提供具有与内部加锁相同内存可见性语义,同时语义、调度算法、顺序保证、性能特性这些可以不同——即功能可以更强大,但是基本核心底层功能不能丢失。

    

   ReentrantLock实现了Lock接口,那么看看这个接口实现是如何在保证内部锁功能同时显式调用的。通常调用范式如下:

    

  譬如CyclicBarrier中的实现:

    

   阅读ReentrantLock源码可知其实现使用了AQS:

    

  ReentrantLock只支持独占的获取操作,因此它实现了AQS中的tryAcquire/tryRelease和isHeldExclusively:

    非公平版

     

   通过源码可知ReentrantLock使用同步状态持有锁获取操作的计数,同时还维护了一个owner变量来持有当前拥有的线程标识符。只有在当期线程刚刚获取到锁,或者刚刚释放了锁的时候,才会修改owner。在tryRelease中,检查owner域以确保当期线程在执行一个unlock操作之前已经拥有了锁;在tryAcquire中,使用这个域来区分重进入的获取操作尝试与竞争的获取操作尝试:

    

   当一个线程尝试去获取锁时,tryAcquire会首先请求锁的状态。如果锁未被占有尝试更新锁的状态,表明锁已被占有。因为状态可能在被观察后的几条指令中被修改了,所以tryAcquire使用compareAndSetState来尝试原子地更新状态表明这个锁现在已经被占有,并确保状态自最后一次观察后没有被修改过。假设锁状态表明它已经被占有,如果当前线程是锁的拥有者,那么获取计数会递减;如果当前线程不是锁的拥有者,那么获取操作的阐述会失败。

 

 

 

 

 

 

 

  

 



这篇关于显式锁之ReentrantLock实现的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程