public class ReentrantReadWriteLock extends Object implements ReadWriteLock, Serializable
ReadWriteLock
支持类似的语义
ReentrantLock
实现。
此类具有以下属性:
此类不会强制读写器或写者优先顺序为锁访问。然而,它确实支持一个可选的公平性政策。
一个线程试图获得一个公平的读锁(非可重入)将块如果写锁,或有一个等待写线程。线程将无法获得读锁,直到最古老的当前等待的作家线程已经获得并释放了写锁。当然,如果一个等待的作者放弃它的等待,留下一个或多个读线程作为队列中最长的服务队列中的写锁,那么这些读者将被分配读锁。
一个线程试图获得一个公平的写锁(非可重入)将阻止除非双方的读锁和写锁是免费的(这意味着没有等待的线程)。(注:非阻塞ReentrantReadWriteLock.ReadLock.tryLock()
和ReentrantReadWriteLock.WriteLock.tryLock()
方法不尊重这种公平设置,将立即获得锁,如果它是可能的,无论等待的线程。)
这锁让读者和作家重新阅读或在一个ReentrantLock
风格写锁。不可重入的读者是不允许直到所有写的写线程持有的锁被释放。
此外,一个作家可以获得读锁,但不是反之亦然。在其他应用程序中,可重入性可能是有用的当写锁调用或回调方法执行期间举行读下读锁。如果一个读者试图获得写锁,它将永远不会成功。
可重入性,也允许降级的写锁,读锁,通过获取写锁,那么读锁,然后释放写锁。然而,从一个读锁升级为写锁不可能。
锁捕获过程中的读锁和写锁两个支持中断。
Condition
支持 写入锁提供了一个Condition
实施的行为,以同样的方式,相对于写锁,由ReentrantLock.newCondition()
的Condition
实现对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可用来提高收藏一些使用各种并发。这是典型的价值只有当集合预期的要大,多线程访问的读者比作家的线程,和需要操作的开销比同步开销。例如,这里是一个类使用一个树状图,将大并发访问。
class RWDictionary {
private final Map<String, Data> m = new TreeMap<String, Data>();
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 String[] allKeys() {
r.lock();
try { return m.keySet().toArray(); }
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
超出这些限制的结果将从锁定的方法。
Modifier and Type | Class and Description |
---|---|
static class |
ReentrantReadWriteLock.ReadLock
方法返回的
readLock() 锁。
|
static class |
ReentrantReadWriteLock.WriteLock
方法返回的
writeLock() 锁。
|
Constructor and Description |
---|
ReentrantReadWriteLock()
创建默认的一个新的
ReentrantReadWriteLock (nonfair)排序性能。
|
ReentrantReadWriteLock(boolean fair)
创建具有给定的公平政策的一个新的
ReentrantReadWriteLock 。
|
Modifier and Type | Method and Description |
---|---|
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()
查询如果写锁是由当前线程举行的。
|
ReentrantReadWriteLock.ReadLock |
readLock()
返回用于读取的锁。
|
String |
toString()
返回一个确定此锁的字符串,以及它的锁状态。
|
ReentrantReadWriteLock.WriteLock |
writeLock()
返回用于写入的锁。
|
public ReentrantReadWriteLock()
ReentrantReadWriteLock
(nonfair)排序性能。
public ReentrantReadWriteLock(boolean fair)
ReentrantReadWriteLock
。
fair
-
true
如果锁应该用一个公平的订货策略
public ReentrantReadWriteLock.WriteLock writeLock()
ReadWriteLock
writeLock
接口
ReadWriteLock
public ReentrantReadWriteLock.ReadLock readLock()
ReadWriteLock
readLock
接口
ReadWriteLock
public final boolean isFair()
true
如果锁已经公平设置为true。
true
如果锁已经公平设置为true
protected Thread getOwner()
null
如果不拥有。当这个方法被一个不是所有者的线程调用时,返回值反映了当前锁定状态的最佳努力近似值。例如,业主可以随时
null
即使有线程试图获取锁,但尚未这样做。这种方法的目的是方便的子类,提供更广泛的锁定监控设施的建设。
null
如果不拥有
public int getReadLockCount()
public boolean isWriteLocked()
true
如果任何线程持有的锁,否则写
false
public boolean isWriteLockedByCurrentThread()
true
如果当前线程持有的锁,否则写
false
public int getWriteHoldCount()
public int getReadHoldCount()
protected Collection<Thread> getQueuedWriterThreads()
protected Collection<Thread> getQueuedReaderThreads()
public final boolean hasQueuedThreads()
true
返回不保证其他线程会获取一个锁。这种方法的设计主要是用于监测系统状态。
true
如果可能有其他线程等待获取锁
public final boolean hasQueuedThread(Thread thread)
true
回报并不保证该线程会获取一个锁。这种方法的设计主要是用于监测系统状态。
thread
-螺纹
true
如果给定线程排队等待这个锁
NullPointerException
-如果线程是无效的
public final int getQueueLength()
protected Collection<Thread> getQueuedThreads()
public boolean hasWaiters(Condition condition)
true
收益并不能保证未来的
signal
将唤醒所有线程。这种方法的设计主要是用于监测系统状态。
condition
-条件
true
如果有任何等待的线程
IllegalMonitorStateException
-如果这锁不举行
IllegalArgumentException
-如果给定的条件是不是与此相关的锁
NullPointerException
-如果条件是空的
public int getWaitQueueLength(Condition condition)
condition
-条件
IllegalMonitorStateException
-如果这锁不举行
IllegalArgumentException
-如果给定的条件是不是与此相关的锁
NullPointerException
-如果条件是空的
protected Collection<Thread> getWaitingThreads(Condition condition)
condition
-条件
IllegalMonitorStateException
-如果这锁不举行
IllegalArgumentException
-如果给定的条件是不是与此相关的锁
NullPointerException
-如果条件是空的
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.