关于java:Java并发通过ReentrantReadWriteLock理解AQS的独占模式和共享模式

28次阅读

共计 1072 个字符,预计需要花费 3 分钟才能阅读完成。

大家好,这里是 淇妙小屋 ,一个分享技术,分享生存的博主
以下是我的主页,各个主页同步更新优质博客,创作不易,还请大家点波关注
掘金主页
后续会公布更多 MySQL,Redis,并发,JVM,分布式等面试热点常识,以及 Java 学习路线,面试重点,职业规划,面经等相干博客
转载请表明出处!

1. 类图构造

  • ReadWriteLock 中有一个 Sync 对象,ReadLock 与 WriteLock 共用 Sync 对象,读锁与写锁底层专用的是同一把锁
  • ReentrantReadWriteLock 中有一个 读锁 (ReadLock) 与一个 写锁(WriteLock)

    读锁 共享模式 写锁 独占模式,通过拆散读写锁,进步并发性

  • 读锁正在被应用时,其余线程能够间接取得读锁,不阻塞

    读锁正在被应用时,如果其余线程尝试获得写锁,会阻塞

    写锁正在被应用时,其余线程尝试获取读锁 or 写锁,都会阻塞

2. 个性

  1. 反对偏心锁与非偏心锁,区别在于 readerShouldBlock()writerShouldBlock()的实现不同
  2. 可重入:拿到读锁后,能够再次获取读锁(然而不能再次获取写锁,拿到读锁后如果再次获取写锁,线程会始终阻塞)

    ​ 拿到写锁后,能够再次获取写锁,也能够再次获取读锁

  3. 锁降级:线程拿到写锁后,在获取读锁,而后先开释掉写锁——降级为读锁

3. 办法

办法形容
int getReadLockCount()获取读锁被获取的次数 ( 同步状态 state 进行位运算失去)
int getWriteHoldCount()返回以后线程获取写锁的次数(exclusiveOwnerThread 指向的线程是取得写锁的线程,state 进行位运算失去)
int getReadHoldCount()返回以后线程获取读锁的次数,Sync 外部有个 ThreadLocalHoldCount(继承自 ThreadLocal)保留有每个线程获取读锁的次数

4. 详细分析

4.1 读写状态设计

AQS 通过 同步状态 state 来示意锁(0—锁可用,非 0—锁不可用,可重入锁每重入一次 state+1)

但在 ReentrantReadWriteLock 中 ReadLock 与 WriteLock 共用一个 state,所以就不是这样简略的机制了

32 位的 state 在 ReentrantReadWriteLock 中被划分为了两局部(16+16)

取得读锁,高 16 位 +1(读锁状态——state>>16,读状态不为 0——读锁已被获取)

取得写锁,低 16 位 +1(写锁状态——state&&0x0000FFFF,写状态不为 0——写锁已被获取)

4.2 写锁的获取与开释

4.3 读锁的获取与开释

正文完
 0