图解ReentrantReadWriteLock读写锁的实现原理

ReentrantReadWriteLock读写锁是使用AQS的集大成者,用了独占模式和共享模式。本文和大家一起理解下ReentrantReadWriteLock读写锁的实现原理。,图片,上图是ReentrantReadWriteLock读写锁的类结构图:,读写锁用的同一个sync同步器,那么他们共享同一个state, 这样不会混淆吗?,不会,ReentrantReadWriteLock读写锁使用了AQS中state值得低16位表示写锁得计数,用高16位表示读锁得计数,这样就可以使用同一个AQS同时管理读锁和写锁。,设计一个加锁场景,t1线程加写锁,t2线程加读锁,我们看下它们整个加锁得流程。,图片,图片,图片,图片,图片,上面是整个解锁的流程,下面深入源码验证这个流程。,WriteLock类的lock()方法是加写锁的入口方法。,ReadLock​类的lock()​方法是加读锁的入口方法,调用tryAcquireShared()方法尝试获取读锁,返回负数,失败,加入到队列中。,tryAcquireShared()方法是一个模板方法,AQS类中定义语义,子类实现,如果返回1,表示获取锁成功,还有剩余资源,返回0表示获取成功,没有剩余资源,返回-1表示失败。,doAcquireShared()是在获取读锁失败的时候加入AQS队列的逻辑。,由于上面t1线程加的写锁,所有其他的线程都被阻塞了,只有在t1线程解锁以后,其他线程才能被唤醒,我们现在看下t1线程被唤醒了,会发生什么?,t1线程执行解锁w.unlock()成功,修改AQS中的state。,图片,图片,图片,图片,图片,图片,图片,图片,上面是整个解锁的流程,下面深入源码验证这个流程。,WriteLock类的unlock()方法是入口方法,调用tryRelease()方法释放锁,如果成功,调用unparkSuccessor()方法唤醒线程。,tryRelease()方法是AQS提供的模板方法,返回true表示成功,false失败,由自定义同步器实现。,2.​读锁释放流程,ReadLock​类的unlock()方法是释放共享锁的入口方法。,tryReleaseShared()方法是由AQS提供的模板方法,由自定义同步器实现。,调用doReleaseShared()​方法唤醒等待的线程,这个方法调用的地方有两处,还记得吗,一个这是里的解锁,还有一个是前面加共享锁阻塞的地方,唤醒后获取锁成功,也会调用doReleaseShared()方法。,本文讲解了读写锁ReentrantReadWriteLock的整个加锁、解锁的实现原理,并从源码的角度深入分析,希望对大家有帮助。

文章版权声明

 1 原创文章作者:cmcc,如若转载,请注明出处: https://www.52hwl.com/16978.html

 2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈

 3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)

 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023年3月5日 上午12:00
下一篇 2023年3月7日 下午10:34