ReentrantReadWriteLock源码分析

简介: ReentrantReadWriteLock源码分析

公众号merlinsea


特性:写写互斥,读写互斥,读读共享

锁降级:写线程在获取写锁以后,完成写操作以后可以获取读锁同时释放写锁,即实现了锁降级。


读写锁支持锁降级 为什么不支持锁升级?

答:锁降级是持有写锁的线程,可以进一步持有读锁,因为写锁只能有一个线程持有,因此锁降级不会造成数据的不一致性。锁升级是持有读锁的线程可以进一步持有写锁,因为在读写锁中,读锁可以被多个线程同时持有,如果允许锁升级,那么这些持有读锁的线程都可以申请写锁,这会导致多个线程同时修改共享变量,会造成数据不一致性,因此不支持锁升级。

640.jpg640.jpg

根据上图的代码来解释ReentrantReadWriteLock如何用一个int state变量同时表示读锁和写锁的状态:


java中一个int型的整数是32位,其中用低16位表示写锁的状态,高16位表示读锁的状态
读锁每次重入都加上65536
      0000000000000000  000000000000000
 +    0000000000000001  000000000000000
 --------------------------------------
      0000000000000001  000000000000000
判断有当前有多少线程持有读锁,status>>16
      0000000000000001  000000000000000
>>16
----------------------------------------
     0000000000000000  000000000000001  
写锁每次重入加上1
     0000000000000000  000000000000000
 +   0000000000000000  000000000000001
 --------------------------------------
     0000000000000000  000000000000001
判断有当前线程重入了多少次写锁,status & 65535
    0000000000000001  0000000000000001
  & 0000000000000000  1111111111111111
----------------------------------------
    0000000000000000  0000000000000001


读锁加锁的核心代码

640.jpg


读锁解锁的核心代码注意点:

   1、可以有很多不同的线程持有读锁,故这些持有读锁的线程可以串成一个链表连接。

    2、每个持有读锁的线程内部会记录当前线程重入了多少次读锁 。

   3、每次一个线程释放读锁的时候都要读锁的count--,当某个线程持有读锁次数为0时可以从链表中移除该线程。

640.jpg


写锁加锁核心代码

640.jpg


写锁解锁的核心代码

640.jpg


相关文章
|
设计模式 Java API
StampedLock源码分析(2)
StampedLock也提供了单独读锁和写锁的封装类WriteLockView和ReadLockView,它俩存在的意义就是只讲锁的部分暴露出去,防止外部接口错误加解锁,我觉得符合软件设计模式中的单一职责和接口隔离原则。
65 1
【ReentrantReadWriteLock的实现原理】
【ReentrantReadWriteLock的实现原理】
|
Java API
StampedLock源码分析(1)
之前已经说过了ReentrantLock ReentrantReadWriteLock,可以参考之前的博客。在ReentrantReadWriteLock源码解析文末,我提到了ReentrantReadWriteLock的缺点,就是无法避免写线程饥渴的问题,而今天要说的StampedLock提供了乐观读的API,解决了写饥渴的问题。
54 0
|
3月前
|
存储 Java 开发者
synchronized源码分析解读
该文章主要探讨了Java中synchronized关键字的工作原理及其相关的源码分析,概括了synchronized关键字的基本概念、特性和其实现机制。通过源码分析进一步揭示了synchronized背后的运作原理。
|
6月前
|
Java
ReentrantLock(可重入锁)源码解读与使用
ReentrantLock(可重入锁)源码解读与使用
|
算法
ReentrantReadWriteLock源码分析
ReentrantReadWriteLock源码分析
53 0
ReentrantReadWriteLock源码分析
|
设计模式 Java API
StampedLock源码分析
StampedLock源码分析
86 0
StampedLock源码分析
|
存储 Java
Java并发之AQS源码分析(一)
AQS 全称是 AbstractQueuedSynchronizer,顾名思义,是一个用来构建锁和同步器的框架,它底层用了 CAS 技术来保证操作的原子性,同时利用 FIFO 队列实现线程间的锁竞争,将基础的同步相关抽象细节放在 AQS,这也是 ReentrantLock、CountDownLatch 等同步工具实现同步的底层实现机制。它能够成为实现大部分同步需求的基础,也是 J.U.C 并发包同步的核心基础组件。
124 0
Java并发之AQS源码分析(一)
|
安全 Java
Java并发之AQS源码分析(二)
我在 Java并发之AQS源码分析(一)这篇文章中,从源码的角度深度剖析了 AQS 独占锁模式下的获取锁与释放锁的逻辑,如果你把这部分搞明白了,再看共享锁的实现原理,思路就会清晰很多。下面我们继续从源码中窥探共享锁的实现原理。
150 0
Java并发之AQS源码分析(二)
|
缓存
【JUC】JDK1.8源码分析之ReentrantReadWriteLock(七)
在分析了锁框架的其他类之后,下面进入锁框架中最后一个类ReentrantReadWriteLock的分析,它表示可重入读写锁,ReentrantReadWriteLock中包含了两种锁,读锁ReadLock和写锁WriteLock,可以通过这两种锁实现线程间的同步,下面开始进行分析。
110 0
【JUC】JDK1.8源码分析之ReentrantReadWriteLock(七)