##ReadWriteLock
public interface ReadWriteLock
- ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。
- 只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。
- 与互斥锁相比,读-写锁允许对共享数据进行更高级别的并发访问。
####接口定义方法
Lock readLock() | 返回用于读取操作的锁。 |
Lock writeLock() | 返回用于写入操作的锁。 |
##ReentrantReadWriteLock
public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable
- 支持与 ReentrantLock 类似语义的 ReadWriteLock 实现。
- 支持公平模式和非公平模式两种策略,默认非公平模式。
- 此锁最多支持 65535 个递归写入锁和 65535 个读取锁。试图超出这些限制将导致锁方法抛出 Error。
- 适用于读多写少且对同步有要求的场景。
####重入
此锁允许 reader 和 writer 按照 ReentrantLock 的样式重新获取读取锁或写入锁。在写入线程保持的所有写入锁都已经释放后,才允许重入 reader 使用它们。
####锁降级
重入还允许从写入锁降级为读取锁,其实现方式是:先获取写入锁,然后获取读取锁,最后释放写入锁。但是,从读取锁升级到写入锁是不可能的。
####锁获取的中断
读取锁和写入锁都支持锁获取期间的中断。
####Condition 支持
写入锁提供了一个 Condition 实现,对于写入锁来说,该实现的行为与 ReentrantLock.newCondition() 提供的 Condition 实现对 ReentrantLock 所做的行为相同。当然,此 Condition 只能用于写入锁。
读取锁不支持 Condition,readLock().newCondition() 会抛出 UnsupportedOperationException。
####监测
此类支持一些确定是保持锁还是争用锁的方法。这些方法设计用于监视系统状态,而不是同步控制。
此类行为的序列化方式与内置锁的相同:反序列化的锁处于解除锁状态,无论序列化该锁时其状态如何。
非公平模式 | 连续竞争的非公平锁可能无限期地推迟一个或多个 reader 或 writer 线程,但吞吐量通常要高于公平锁。 |
公平模式 | 当释放当前保持的锁时,可以为等待时间最长的单个 writer 线程分配写入锁,如果有一组等待时间大于所有正在等待的 writer 线程 的 reader 线程,将为该组分配写入锁。 |
ReentrantReadWriteLock.ReadLock readLock():返回用于读取操作的锁。
public ReentrantReadWriteLock.ReadLock readLock() {
return readerLock;
}
ReentrantReadWriteLock.WriteLock writeLock():返回用于读取操作的锁。
public ReentrantReadWriteLock.WriteLock writeLock() {
return writerLock;
}
###WriteLock、ReadLock
public static class ReadLock implements Lock, java.io.Serializable
public static class WriteLock implements Lock, java.io.Serializable
- ReentrantReadWriteLock内部类,提供读写锁相关的支持。
ReadLock
void lock() | 获取读取锁。 |
void lockInterruptibly() | 获取读取锁,除非当前线程被 中断。 |
boolean tryLock() | 仅当写入锁在调用期间未被另一个线程保持时获取读取锁。 |
boolean tryLock(long timeout,TimeUnit unit) | 如果另一个线程在给定的等待时间内没有保持写入锁,并且当前线程未被 中断,则获取读取锁。 |
void unlock() | 试图释放此锁。 |
Condition newCondition() | 因为 ReadLocks 不支持条件,所以将抛出 UnsupportedOperationException。 |
String toString() | 返回标识此锁及其锁状态的字符串。括号中的状态包括字符串 "Read locks =",后跟读取锁的数量。 |
WriteLock定义方法与ReadLock类似,只不过一个是写、一个是读。但WriteLock多了两个方法:getHoldCount(查询当前线程保持写入锁的数量。), isHeldByCurrentThread(查询此写入锁是否由当前线程保持。),另外WriteLock支持newCondition方法。
其实ReentrantReadWriteLock和ReentrantLock类似,只不过将读写锁分离,且读取锁是共享的,写入锁是互斥的,允许从写入锁降级为读取锁,但是,从读取锁升级到写入锁是不可能的。底层都是基于CAS,支持公平和非公平两种策略模式。