- 读写锁维护一对锁,读锁和写锁
- 分离读锁和写锁,并发性比排它锁有很大提升
- ReadWriteLock仅定义读锁和写锁的两个方法——readLock()和writeLock()
- 实现类ReentrantReadWriteLock提供了以下方法:
方法 | 描述 |
---|---|
int getReadLockCount() | 返回当前读锁被获取的次数。该次数不等于获取读锁的线程数,比如:仅一个线程,它连续获取(重进入)了n次读锁,那么占据读锁的线程数是1,但该方法返回n |
int getReadHoldCount() | 返回当前线程获取读锁的次数。该方法在Java 6 中加入到ReentrantReadWriteLock中,使用ThreadLocal保存当前线程获取的次数,这也使得Java 6 的实现变得更加复杂 |
boolean isWriteLocked() | 判断写锁是否被获取 |
int getWriteHoldCount() | 返回当前写锁被获取的次数 |
-
读写锁状态的设计:
- 通过运用“按位切割使用”同步状态(一个整形变量),来维护多个读线程和一个写线程。(高16位读,底16位写)。
- 锁状态S不等于0时,当写状态(S&0x0000FFFF)等于0时,则读状态(S>>>16)大于0,读锁已被获取。
-
写锁的获取和释放:
- 写锁支持重进入:
- 当前线程获取了写锁,增加写状态
- 当前线程获取写锁时,读锁已经被获取或者线程不是获取写锁的进程,当前线程进入等待状态
- 写锁支持重进入:
-
读锁的获取和释放
- 读锁可以被多个线程同时获取,没有其他线程访问或者写状态为0,读锁总是可以获取成功,并增加读状态
- 如果写锁被其他线程获取了。读锁进入等待状态
-
锁降级
- 写锁降级成读锁:把当前持有的写锁,再获取到读锁,随后释放(之前拥有的)写锁
- 锁降级作用:如果线程获取读锁而是直接释放写锁,假设某线程获取了写锁并修改了数据,当前线程无法获取数据更新了。
- ReentrantReadWriteLock不支持锁升级,也是因为如果读锁被多个线程获取,任意线程获取了写锁并更新数据,其更新对其他获取到读锁的线程是不可见的。
网友评论