- java.lang.Object
-
- java.util.concurrent.locks.ReentrantReadWriteLock
-
- 实现的所有接口
-
Serializable
,ReadWriteLock
public class ReentrantReadWriteLock extends Object implements ReadWriteLock, Serializable
的实现ReadWriteLock
支持类似的语义ReentrantLock
。该类具有以下属性:
- 收购订单
此类不会强制执行锁定访问的读取器或编写器首选项顺序。 但是,它确实支持可选的公平政策。
- 非公平模式(默认)
- 当构造为非公平(默认)时,读取和写入锁定的输入顺序是未指定的,受重入约束的限制。 持续争用的非公平锁定可能无限期地推迟一个或多个读取器或写入器线程,但通常具有比公平锁定更高的吞吐量。
- 公平模式
-
当构造为公平时,线程使用近似到达顺序策略争用进入。
当释放当前保持的锁定时,将为最长等待的单个写入器线程分配写入锁定,或者如果有一组读取器线程等待的时间长于所有等待的写入器线程,则将为该组分配读取锁定。
尝试获取公平读锁定(非重复)的线程将阻止是否保持写锁定,或者存在等待写入器线程。 在最旧的当前等待的写入器线程获取并释放写锁定之前,线程将不会获取读锁定。 当然,如果等待的写入者放弃其等待,将一个或多个读取器线程作为队列中最长的服务器并且写锁定空闲,那么将为这些读取器分配读锁定。
尝试获取公平写锁定(非重复)的线程将阻塞,除非读取锁定和写入锁定都是空闲的(这意味着没有等待的线程)。 (请注意,非阻塞
ReentrantReadWriteLock.ReadLock.tryLock()
和ReentrantReadWriteLock.WriteLock.tryLock()
方法不遵循此公平设置,并且如果可能,将立即获取锁定,无论等待线程如何。)
- 重入
此锁允许读取器和写入器以
ReentrantLock
的样式重新获取读或写锁。 在写入线程持有的所有写锁定都被释放之前,不允许使用非重入读取器。此外,编写器可以获取读锁定,但反之亦然。 在其他应用程序中,在调用期间保持写入锁定或在对读取锁定执行读取的方法的回调时,重入可能很有用。 如果读者试图获取写锁定,它将永远不会成功。
- 锁定降级
Reentrancy还允许通过获取写锁定,然后读取锁定然后释放写入锁定,从写入锁定降级到读取锁定。 然而,从读锁定写锁定升级是不可能的。
- 锁定获取中断
读取锁定和写入锁定都支持锁定获取期间的中断。
-
Condition
支持写锁定提供
Condition
实现,相对于写锁定,其行为方式相同,因为ReentrantLock.newCondition()
提供的Condition
实现针对ReentrantLock
。 当然,这个Condition
只能与写锁一起使用。读锁定不支持
Condition
和readLock().newCondition()
抛出UnsupportedOperationException
。 - 仪表
此类支持确定锁是保持还是争用的方法。 这些方法用于监视系统状态,而不是用于同步控制。
此类的序列化与内置锁的行为方式相同:反序列化锁处于解锁状态,无论序列化时的状态如何。
示例用法 。 下面是一个代码草图,展示了如何在更新缓存后执行锁定降级(在以非嵌套方式处理多个锁时,异常处理尤其棘手):
class CachedData { Object data; boolean cacheValid; final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); void processCachedData() { rwl.readLock().lock(); if (!cacheValid) { // Must release read lock before acquiring write lock rwl.readLock().unlock(); rwl.writeLock().lock(); try { // Recheck state because another thread might have // acquired write lock and changed state before we did. if (!cacheValid) { data = ... cacheValid = true; } // Downgrade by acquiring read lock before releasing write lock rwl.readLock().lock(); } finally { rwl.writeLock().unlock(); // Unlock write, still hold read } } try { use(data); } finally { rwl.readLock().unlock(); } } }
class RWDictionary { private final Map<String, Data> m = new TreeMap<>(); private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); private final Lock r = rwl.readLock(); private final Lock w = rwl.writeLock(); public Data get(String key) { r.lock(); try { return m.get(key); } finally { r.unlock(); } } public List<String> allKeys() { r.lock(); try { return new ArrayList<>(m.keySet()); } finally { r.unlock(); } } public Data put(String key, Data value) { w.lock(); try { return m.put(key, value); } finally { w.unlock(); } } public void clear() { w.lock(); try { m.clear(); } finally { w.unlock(); } } }
实施说明
此锁最多支持65535个递归写锁和65535个读锁。 尝试超过这些限制会导致锁定方法引发
Error
次抛出。- 从以下版本开始:
- 1.5
- 另请参见:
- Serialized Form
-
-
嵌套类汇总
嵌套类 变量和类型 类 描述 static class
ReentrantReadWriteLock.ReadLock
方法ReadWriteLock.readLock()
返回的锁定。static class
ReentrantReadWriteLock.WriteLock
方法ReadWriteLock.writeLock()
返回的锁定。
-
构造方法摘要
构造方法 构造器 描述 ReentrantReadWriteLock()
使用默认(非公平)排序属性创建新的ReentrantReadWriteLock
。ReentrantReadWriteLock(boolean fair)
使用给定的公平政策创建新的ReentrantReadWriteLock
。
-
方法摘要
所有方法 实例方法 具体的方法 变量和类型 方法 描述 protected Thread
getOwner()
返回当前拥有写锁定的线程,如果不拥有,则返回null
。protected Collection<Thread>
getQueuedReaderThreads()
返回包含可能正在等待获取读锁定的线程的集合。protected Collection<Thread>
getQueuedThreads()
返回包含可能正在等待获取读取或写入锁定的线程的集合。protected Collection<Thread>
getQueuedWriterThreads()
返回包含可能正在等待获取写锁定的线程的集合。int
getQueueLength()
返回等待获取读锁定或写锁定的线程数的估计值。int
getReadHoldCount()
查询当前线程对此锁定的重入读取保留的数量。int
getReadLockCount()
查询为此锁保存的读锁数。protected Collection<Thread>
getWaitingThreads(Condition condition)
返回一个集合,其中包含可能正在等待与写入锁定关联的给定条件的那些线程。int
getWaitQueueLength(Condition condition)
返回在与写锁定关联的给定条件上等待的线程数的估计值。int
getWriteHoldCount()
查询当前线程对此锁定的可重入写保持的数量。boolean
hasQueuedThread(Thread thread)
查询给定线程是否正在等待获取读或写锁。boolean
hasQueuedThreads()
查询是否有任何线程正在等待获取读或写锁。boolean
hasWaiters(Condition condition)
查询是否有任何线程正在等待与写锁定相关联的给定条件。boolean
isFair()
如果此锁定的公平性设置为true,则返回true
。boolean
isWriteLocked()
查询是否由任何线程持有写锁定。boolean
isWriteLockedByCurrentThread()
查询当前线程是否持有写锁定。String
toString()
返回标识此锁的字符串及其锁定状态。-
声明方法的类 java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
-
声明方法的接口 java.util.concurrent.locks.ReadWriteLock
readLock, writeLock
-
-
-
-
方法详细信息
-
isFair
public final boolean isFair()
如果此锁定的公平性设置为true,则返回true
。- 结果
-
true
如果此锁定的公平性设置为真
-
getOwner
protected Thread getOwner()
返回当前拥有写锁定的线程,如果不拥有,则返回null
。 当此方法由非所有者的线程调用时,返回值反映当前锁定状态的尽力近似值。 例如,即使有线程尝试获取锁定但尚未执行此操作,所有者可能暂时为null
。 该方法旨在便于构建提供更广泛的锁定监视设施的子类。- 结果
-
所有者,如果不拥有,
null
-
getReadLockCount
public int getReadLockCount()
查询为此锁保存的读锁数。 此方法设计用于监视系统状态,而不是用于同步控制。- 结果
- 持有的读锁数
-
isWriteLocked
public boolean isWriteLocked()
查询是否由任何线程持有写锁定。 此方法设计用于监视系统状态,而不是用于同步控制。- 结果
-
true
如果有任何线程持有写锁定,否则为false
-
isWriteLockedByCurrentThread
public boolean isWriteLockedByCurrentThread()
查询当前线程是否持有写锁定。- 结果
-
true
如果当前线程保持写锁定,否则为false
-
getWriteHoldCount
public int getWriteHoldCount()
查询当前线程对此锁定的可重入写保持的数量。 作者线程对每个与解锁操作不匹配的锁定操作保持锁定。- 结果
- 当前线程对写锁定的保持次数,如果当前线程未保持写锁定,则为零
-
getReadHoldCount
public int getReadHoldCount()
查询当前线程对此锁定的重入读取保留的数量。 读取器线程对每个与解锁操作不匹配的锁定操作保持锁定。- 结果
- 当前线程在读锁定上的保持次数,如果当前线程未保持读锁定,则为零
- 从以下版本开始:
- 1.6
-
getQueuedWriterThreads
protected Collection<Thread> getQueuedWriterThreads()
返回包含可能正在等待获取写锁定的线程的集合。 因为实际的线程集可能在构造此结果时动态更改,所以返回的集合仅是尽力而为的估计。 返回集合的元素没有特定的顺序。 该方法旨在便于构建提供更广泛的锁定监视设施的子类。- 结果
- 线程集合
-
getQueuedReaderThreads
protected Collection<Thread> getQueuedReaderThreads()
返回包含可能正在等待获取读锁定的线程的集合。 因为实际的线程集可能在构造此结果时动态更改,所以返回的集合仅是尽力而为的估计。 返回集合的元素没有特定的顺序。 该方法旨在便于构建提供更广泛的锁定监视设施的子类。- 结果
- 线程集合
-
hasQueuedThreads
public final boolean hasQueuedThreads()
查询是否有任何线程正在等待获取读或写锁。 请注意,由于取消可能随时发生,因此true
返回不保证任何其他线程将获得锁定。 该方法主要用于监视系统状态。- 结果
-
true
如果有其他线程等待获取锁定
-
hasQueuedThread
public final boolean hasQueuedThread(Thread thread)
查询给定线程是否正在等待获取读或写锁。 请注意,由于取消可能随时发生,因此true
返回并不保证此线程将获得锁定。 该方法主要用于监视系统状态。- 参数
-
thread
- 该主题 - 结果
-
true
如果给定线程排队等待此锁定 - 异常
-
NullPointerException
- 如果线程为null
-
getQueueLength
public final int getQueueLength()
返回等待获取读锁定或写锁定的线程数的估计值。 该值只是一个估计值,因为当此方法遍历内部数据结构时,线程数可能会动态更改。 此方法设计用于监视系统状态,而不是用于同步控制。- 结果
- 等待此锁定的估计线程数
-
getQueuedThreads
protected Collection<Thread> getQueuedThreads()
返回包含可能正在等待获取读取或写入锁定的线程的集合。 因为实际的线程集可能在构造此结果时动态更改,所以返回的集合仅是尽力而为的估计。 返回集合的元素没有特定的顺序。 该方法旨在便于构建提供更广泛监控设施的子类。- 结果
- 线程集合
-
hasWaiters
public boolean hasWaiters(Condition condition)
查询是否有任何线程正在等待与写锁定相关联的给定条件。 请注意,由于超时和中断可能随时发生,true
返回并不能保证未来的signal
会唤醒任何线程。 该方法主要用于监视系统状态。- 参数
-
condition
- 条件 - 结果
-
true
如果有任何等待线程 - 异常
-
IllegalMonitorStateException
- 如果未锁定此锁定 -
IllegalArgumentException
- 如果给定条件与此锁定无关 -
NullPointerException
- 如果条件为空
-
getWaitQueueLength
public int getWaitQueueLength(Condition condition)
返回在与写锁定关联的给定条件上等待的线程数的估计值。 请注意,由于超时和中断可能在任何时间发生,因此估计仅用作实际服务员数量的上限。 此方法设计用于监视系统状态,而不是用于同步控制。- 参数
-
condition
- 条件 - 结果
- 估计的等待线程数
- 异常
-
IllegalMonitorStateException
- 如果未锁定此锁定 -
IllegalArgumentException
- 如果给定条件与此锁无关 -
NullPointerException
- 如果条件为null
-
getWaitingThreads
protected Collection<Thread> getWaitingThreads(Condition condition)
返回一个集合,其中包含可能正在等待与写入锁定关联的给定条件的那些线程。 因为实际的线程集可能在构造此结果时动态更改,所以返回的集合仅是尽力而为的估计。 返回集合的元素没有特定的顺序。 该方法旨在便于构建提供更广泛的状态监测设施的子类。- 参数
-
condition
- 条件 - 结果
- 线程集合
- 异常
-
IllegalMonitorStateException
- 如果未锁定此锁定 -
IllegalArgumentException
- 如果给定条件与此锁定无关 -
NullPointerException
- 如果条件为null
-
-