第 6 章 Java 并发包中锁原理剖析Part two

目录

6.3 读写锁 ReentrantReadWriteLock 的原理

写锁的获取与释放 

1.void lock()

 2.void lockInterruptibly()

3.boolean tryLock()

4.boolean tryLock(long timeout, TimeUnit unit)

5.释放锁 void unlock()

读锁的获取与释放

1.void lock()

2.void lockInterruptibly()

3.boolean tryLock()

4.boolean tryLock(long timeout, TimeUnit unit)

5.void unlock()


6.3 读写锁 ReentrantReadWriteLock 的原理

解决线程安全问题使用 ReentrantLock 就可以,但是 ReentrantLock 是独占锁,某时只
有一个线程可以获取该锁,而实际中会有写少读多的场景,显然 ReentrantLock 满足不了
这个需求,所以 ReentrantReadWriteLock 应运而生。 ReentrantReadWriteLock 采用读写分 离的策略,允许多个线程可以同时获取读锁。
读写锁的内部维护了一个 ReadLock 和一个 WriteLock ,它们依赖 Sync 实现具体功能。
Sync 继承自 AQS,并且也提供了公平和非公平的实现。[这里说的是非公平锁],我们知道 AQS 中只维护了一个 state 状态,而 ReentrantReadWriteLock 则需要维护读状态和写状态,一个 state 怎么表示写和读两种状态呢 ?

ReentrantReadWriteLock 巧妙地使用 state 16 位表示读状态,也就是获取到读锁的次数 ;使用16 位表示获取到写锁的线程的可重入次数

  • firstReader 用来记录第一个获取到读锁的线程
  • firstReaderHoldCount 则记录第一个获取到读锁的线程获取读锁的可重入次数
  • cachedHoldCounter 用来记录最后一个获取读锁的线程获取读锁的可重入次数
  • readHolds ThreadLocal 变量,用来存放除去第一个获取读锁线程外的其他线程获取 读锁的可重入次数
static final int SHARED_SHIFT = 16;

//共享锁(读锁)状态单位值65536 
static final int SHARED_UNIT = (1 << SHARED_SHIFT);

//共享锁线程最大个数65535
static final int MAX_COUNT = (1 << SHARED_SHIFT) - 1;

//排它锁(写锁)掩码, 二进制 ,15个1
static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;

/** 返回读锁线程数 */
static int sharedCount(int c) { return c >>> SHARED_SHIFT; }
/** 返回写锁可重入个数 */
static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值