ReentrantLock源码
2022-12-06 21:13 杭伟 阅读(36) 评论(0) 收藏 举报ReentrantLock即是AQS线程同步队列器思想的具体应用/实现
实现了AQS,并有公平锁和非公平锁(默认非公平锁)两种实现


ReentrantLock有三个重要的内部类:Sync(抽象类),NonfaireSync(Sync的非公平锁实现),FairSync(Sync的公平锁实现)
Sync抽象类

Sync继承AQS,
nonfairTryAcquire()方法
如果State=0,尝试CAS获取锁;
否则,判断当前线程是不是已经拿到锁的线程(可重入=一个线程获取了锁再次尝试获取锁时不会出现死锁)

并累加State来记录重入次数。
*小细节:因为State是从0开始的累加值,为什么会判断nextc<0? 因为int为16位最大值为2147483647(允许重入的最大次数),超出即溢出为负数。
tryRelease()方法
实现的AQS的tryRelease

返回值代表的是:是否完全被释放。
NonfaireSync(非公平锁)实现类
NonfairSync继承Sync
lock()方法

非公平锁的lock方法,可以看到,上来就给一次机会,通过CAS设置全局状态值为1,设置成功即抢到锁。
这个机会抢不到,则使用AQS的acquire()方法去排队。
而公平锁那边的实现:直接去排队。
tryAcquire()方法 【override】
非公平锁中acquire()会调用tryAcquire()

tryAcquire()调用nonfairTryAcquire()
在这里可以看到,非公平锁进行了2次CAS操作来尝试获取锁。若2次都失败,则去排队。
细节:为什么nonfairTryAcquire()方法会被定义在Sync抽象类(而不是非公平锁的实现类)中?
FairSync(公平锁)实现类
FairSync继承Sync
lock()方法
直接调用AQS的acquire()方法排队

AQS中acquire方法会调用tryAcquire方法。
tryAcquire()方法 【override】

如果锁空闲 并且 当前线程之前没有线程(即当前线程在队头,即排队排到我了) ,后面是一个短路与符号&&,则开始CAS获取锁,
后面的逻辑基本与前面的非公平锁一样。
这里保持了FIFO队列的公平特性,排队思想。
作者:hangwei
出处:http://www.cnblogs.com/hangwei/
关于作者:专注于开源平台,分布式系统的架构设计与开发、数据库性能调优等工作。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
如果您觉得文章对您有帮助,可以点击文章右下角“推荐”一下。您的鼓励是作者坚持原创和持续写作的最大动力!
浙公网安备 33010602011771号