public class ReentrantReadWriteLock
extends Object
implements ReadWriteLock, Serializable
java.lang.Object | |
↳ | java.util.concurrent.locks.ReentrantReadWriteLock |
一个实现 ReadWriteLock
支持类似的语义到 ReentrantLock
。
这个类有以下属性:
该类不强制为锁访问订购读者或写者偏好。 但是,它支持可选的公平策略。
尝试获得公平读取锁定(非重复)的线程会阻止写入锁定,或者存在等待写入器线程。 直到最早的当前正在等待的写入线程获取并释放写入锁定之后,线程才会获取读取锁定。 当然,如果一个等待写作者放弃等待,留下一个或多个读者线程作为队列中最长的等待者并且写锁定是空闲的,那么这些读者将被分配读锁。
除非读锁和写锁都是空闲的(这意味着没有等待线程),否则试图获得公平写锁的线程(非再生)将被阻塞。 (请注意,非阻塞tryLock()
和tryLock()
方法不符合此公平设置,并且如果可能,将立即获取该锁,而不管等待的线程如何。)
此锁允许读者和作者以ReentrantLock
的样式重新获取读取或写入锁定。 直到写入线程持有的所有写入锁定都被释放后才允许不可重入读取器。
另外,作者可以获取读锁,但反之亦然。 在其他应用程序中,当在执行读取锁定下执行读取的方法的调用或回调期间保持写入锁定时,重新进入可能很有用。 如果读者试图获得写入锁,它永远不会成功。
重入还允许通过获取写入锁定,然后读取锁定,然后释放写入锁定,从写入锁定降级到读取锁定。 然而,从读锁定写锁定升级是不可能的。
读取锁定和写入锁定均支持锁定采集期间的中断。
Condition
support 写锁提供了一个Condition
实现,其行为与写锁相同,因为Condition
提供的newCondition()
实现为ReentrantLock
提供了实现。 当然,这个Condition
只能与写入锁一起使用。
读锁不支持 Condition
和 readLock().newCondition()
抛出 UnsupportedOperationException
。
该类支持确定锁是持有还是争用的方法。 这些方法用于监视系统状态,而不是用于同步控制。
该类的序列化行为与内置锁的行为相同:反序列化的锁处于解锁状态,无论序列化时的状态如何。
样本用法 。 下面是一段代码草图,展示了如何在更新缓存后执行锁定降级(当以非嵌套方式处理多个锁时,异常处理特别棘手):
class CachedData {
Object data;
volatile 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();
}
}
}
ReentrantReadWriteLocks can be used to improve concurrency in some uses of some kinds of Collections. This is typically worthwhile only when the collections are expected to be large, accessed by more reader threads than writer threads, and entail operations with overhead that outweighs synchronization overhead. For example, here is a class using a TreeMap that is expected to be large and concurrently accessed.
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
从锁定方法中抛出。
Nested classes |
|
---|---|
class |
ReentrantReadWriteLock.ReadLock 由方法 |
class |
ReentrantReadWriteLock.WriteLock 方法 |
Public constructors |
|
---|---|
ReentrantReadWriteLock() 使用默认(非公平)排序属性创建一个新的 |
|
ReentrantReadWriteLock(boolean fair) 用给定的公平策略创建一个新的 |
Public methods |
|
---|---|
final int |
getQueueLength() 返回等待获取读取或写入锁定的线程数的估计值。 |
int |
getReadHoldCount() 查询当前线程在此锁上保留的重入读取次数。 |
int |
getReadLockCount() 查询为此锁持有的读锁的数量。 |
int |
getWaitQueueLength(Condition condition) 返回等待与写入锁定关联的给定条件的线程数量的估计值。 |
int |
getWriteHoldCount() 查询当前线程在此锁上保留的重入写入的数量。 |
final boolean |
hasQueuedThread(Thread thread) 查询给定线程是否正在等待获取读锁或写锁。 |
final boolean |
hasQueuedThreads() 查询是否有线程正在等待获取读取或写入锁定。 |
boolean |
hasWaiters(Condition condition) 查询是否有任何线程正在等待与写入锁定关联的给定条件。 |
final boolean |
isFair() 如果此锁定公平设置为true,则返回 |
boolean |
isWriteLocked() 查询写锁是否被任何线程保存。 |
boolean |
isWriteLockedByCurrentThread() 查询当前线程是否保持写入锁定。 |
ReentrantReadWriteLock.ReadLock |
readLock() 返回用于读取的锁。 |
String |
toString() 返回标识此锁定的字符串以及其锁定状态。 |
ReentrantReadWriteLock.WriteLock |
writeLock() 返回用于写入的锁。 |
Protected methods |
|
---|---|
Thread |
getOwner() 返回当前拥有写入锁定的线程,如果不是,则返回 |
Collection<Thread> |
getQueuedReaderThreads() 返回包含可能正在等待获取读锁的线程的集合。 |
Collection<Thread> |
getQueuedThreads() 返回包含可能正在等待获取读取或写入锁定的线程的集合。 |
Collection<Thread> |
getQueuedWriterThreads() 返回包含可能正在等待获取写入锁定的线程的集合。 |
Collection<Thread> |
getWaitingThreads(Condition condition) 返回一个集合,它包含那些可能正在等待与写入锁定关联的给定条件的线程。 |
Inherited methods |
|
---|---|
From class java.lang.Object
|
|
From interface java.util.concurrent.locks.ReadWriteLock
|
ReentrantReadWriteLock ()
使用默认(非公平)排序属性创建一个新的 ReentrantReadWriteLock
。
ReentrantReadWriteLock (boolean fair)
用给定的公平策略创建一个新的 ReentrantReadWriteLock
。
Parameters | |
---|---|
fair |
boolean : true if this lock should use a fair ordering policy |
int getQueueLength ()
返回等待获取读取或写入锁定的线程数的估计值。 该值仅为估计值,因为在此方法遍历内部数据结构时,线程数可能会动态变化。 此方法设计用于监视系统状态,而不是用于同步控制。
Returns | |
---|---|
int |
the estimated number of threads waiting for this lock |
int getReadHoldCount ()
查询当前线程在此锁上保留的重入读取次数。 阅读器线程对每个锁定操作都有一个锁定,但与解锁操作不匹配。
Returns | |
---|---|
int |
the number of holds on the read lock by the current thread, or zero if the read lock is not held by the current thread |
int getReadLockCount ()
查询为此锁持有的读锁的数量。 此方法设计用于监视系统状态,而不是用于同步控制。
Returns | |
---|---|
int |
the number of read locks held |
int getWaitQueueLength (Condition condition)
返回等待与写入锁定关联的给定条件的线程数量的估计值。 请注意,因为超时和中断可能随时发生,所以估计仅作为服务员实际数量的上限。 此方法设计用于监视系统状态,而不是用于同步控制。
Parameters | |
---|---|
condition |
Condition : the condition |
Returns | |
---|---|
int |
the estimated number of waiting threads |
Throws | |
---|---|
IllegalMonitorStateException |
if this lock is not held |
IllegalArgumentException |
if the given condition is not associated with this lock |
NullPointerException |
if the condition is null |
int getWriteHoldCount ()
查询当前线程在此锁上保留的重入写入的数量。 编写器线程对每个未与解锁操作匹配的锁定操作锁定一个锁定。
Returns | |
---|---|
int |
the number of holds on the write lock by the current thread, or zero if the write lock is not held by the current thread |
boolean hasQueuedThread (Thread thread)
查询给定线程是否正在等待获取读锁或写锁。 请注意,由于取消可能随时发生, true
退回并不能保证此线程会获得锁定。 此方法主要用于监视系统状态。
Parameters | |
---|---|
thread |
Thread : the thread |
Returns | |
---|---|
boolean |
true if the given thread is queued waiting for this lock |
Throws | |
---|---|
NullPointerException |
if the thread is null |
boolean hasQueuedThreads ()
查询是否有线程正在等待获取读取或写入锁定。 请注意,因为取消可能随时发生,所以true
退回并不能保证任何其他线程都会获得锁定。 此方法主要用于监视系统状态。
Returns | |
---|---|
boolean |
true if there may be other threads waiting to acquire the lock |
boolean hasWaiters (Condition condition)
查询是否有任何线程正在等待与写入锁定关联的给定条件。 请注意,因为超时和中断可能随时发生,所以true
返回不能保证将来signal
将唤醒任何线程。 此方法主要用于监视系统状态。
Parameters | |
---|---|
condition |
Condition : the condition |
Returns | |
---|---|
boolean |
true if there are any waiting threads |
Throws | |
---|---|
IllegalMonitorStateException |
if this lock is not held |
IllegalArgumentException |
if the given condition is not associated with this lock |
NullPointerException |
if the condition is null |
boolean isFair ()
如果此锁定公平设置为true,则返回 true
。
Returns | |
---|---|
boolean |
true if this lock has fairness set true |
boolean isWriteLocked ()
查询写锁是否被任何线程保存。 此方法设计用于监视系统状态,而不是用于同步控制。
Returns | |
---|---|
boolean |
true if any thread holds the write lock and false otherwise |
boolean isWriteLockedByCurrentThread ()
查询当前线程是否保持写入锁定。
Returns | |
---|---|
boolean |
true if the current thread holds the write lock and false otherwise |
ReentrantReadWriteLock.ReadLock readLock ()
返回用于读取的锁。
Returns | |
---|---|
ReentrantReadWriteLock.ReadLock |
the lock used for reading |
String toString ()
返回标识此锁定的字符串以及其锁定状态。 括号中的状态包括字符串"Write locks ="
后面跟着重写的写入锁的数量,字符串"Read locks ="
后面跟着持有的读取锁的数量。
Returns | |
---|---|
String |
a string identifying this lock, as well as its lock state |
ReentrantReadWriteLock.WriteLock writeLock ()
返回用于写入的锁。
Returns | |
---|---|
ReentrantReadWriteLock.WriteLock |
the lock used for writing |
Thread getOwner ()
返回当前拥有写入锁定的线程,如果不是,则返回null
。 当此方法由非所有者的线程调用时,返回值反映当前锁状态的尽力而为的近似值。 例如,即使有线程试图获取锁但尚未这样做,拥有者可能会暂时为null
。 该方法旨在便于建造提供更广泛锁定监控设施的子类。
Returns | |
---|---|
Thread |
the owner, or null if not owned |
Collection<Thread> getQueuedReaderThreads ()
返回包含可能正在等待获取读锁的线程的集合。 因为实际的一组线程可能会在构造这个结果时动态地改变,所以返回的集合只是一个尽力而为的估计。 返回的集合的元素没有特定的顺序。 该方法旨在便于建造提供更广泛锁定监控设施的子类。
Returns | |
---|---|
Collection<Thread> |
the collection of threads |
Collection<Thread> getQueuedThreads ()
返回包含可能正在等待获取读取或写入锁定的线程的集合。 因为实际的一组线程可能会在构造这个结果时动态地改变,所以返回的集合只是一个尽力而为的估计。 返回的集合的元素没有特定的顺序。 该方法旨在促进提供更广泛监测设施的子类的构建。
Returns | |
---|---|
Collection<Thread> |
the collection of threads |
Collection<Thread> getQueuedWriterThreads ()
返回包含可能正在等待获取写入锁定的线程的集合。 因为实际的一组线程可能会在构造这个结果时动态地改变,所以返回的集合只是一个尽力而为的估计。 返回的集合的元素没有特定的顺序。 该方法旨在便于建造提供更广泛锁定监控设施的子类。
Returns | |
---|---|
Collection<Thread> |
the collection of threads |
Collection<Thread> getWaitingThreads (Condition condition)
返回一个集合,它包含那些可能正在等待与写入锁定关联的给定条件的线程。 因为实际的一组线程可能会在构造这个结果时动态地改变,所以返回的集合只是一个尽力而为的估计。 返回的集合的元素没有特定的顺序。 这种方法旨在促进提供更广泛的状态监测设施的子类的构建。
Parameters | |
---|---|
condition |
Condition : the condition |
Returns | |
---|---|
Collection<Thread> |
the collection of threads |
Throws | |
---|---|
IllegalMonitorStateException |
if this lock is not held |
IllegalArgumentException |
if the given condition is not associated with this lock |
NullPointerException |
if the condition is null |