public class StampedLock extends Object implements Serializable
writeLock()
可能阻止等待独占访问,返回可以在方法unlockWrite(long)
中使用的邮票来释放锁定。 不定时的和定时版本tryWriteLock
,还提供。 当锁保持写入模式时,不能获得读取锁定,并且所有乐观读取验证都将失败。 readLock()
可能阻止等待非独占访问,返回可用于方法unlockRead(long)
释放锁的戳记 。 不定时的和定时版本tryReadLock
,还提供。 tryOptimisticRead()
只有当锁当前未保持在写入模式时才返回非零标记。 方法validate(long)
返回true,如果在获取给定的邮票时尚未在写入模式中获取锁定。 这种模式可以被认为是一个非常弱的版本的读锁,可以随时由作家打破。 对简单的只读代码段使用乐观模式通常会减少争用并提高吞吐量。 然而,其使用本质上是脆弱的。 乐观阅读部分只能读取字段并将其保存在局部变量中,以供后验证使用。 以乐观模式读取的字段可能会非常不一致,因此只有在熟悉数据表示以检查一致性和/或重复调用方法validate()
时,使用情况才适用。 例如,当首次读取对象或数组引用,然后访问其字段,元素或方法之一时,通常需要这样的步骤。 此类还支持有条件地在三种模式下提供转换的方法。 例如,方法tryConvertToWriteLock(long)
尝试“升级”模式,如果(1)在读取模式下已经在写入模式(2)中并且没有其他读取器或(3)处于乐观模式并且锁可用,则返回有效写入戳记。 这些方法的形式旨在帮助减少在基于重试的设计中出现的一些代码膨胀。
StampedLocks设计用作线程安全组件开发中的内部实用程序。 他们的使用依赖于他们保护的数据,对象和方法的内部属性的知识。 它们不是可重入的,所以锁定的机构不应该调用其他可能尝试重新获取锁的未知方法(尽管您可以将戳记传递给可以使用或转换它的其他方法)。 读锁定模式的使用依赖于相关的代码段是无副作用的。 未经验证的乐观阅读部分不能调用不知道容忍潜在不一致的方法。 邮票使用有限表示,并且不是加密安全的(即,有效的邮票可能是可猜测的)。 邮票值可以在连续运行一年后(不早于)回收。 不超过此期限使用或验证的邮票可能无法正确验证。 StampedLocks是可序列化的,但总是反序列化为初始解锁状态,因此它们对于远程锁定无用。
StampedLock的调度策略不一致优先于读者,反之亦然。 所有“尝试”方法都是尽力而为,并不一定符合任何调度或公平政策。 用于获取或转换锁定的任何“try”方法的零返回不携带关于锁的状态的任何信息; 随后的调用可能会成功。
因为它支持跨多个锁模式的协调使用,所以该类不直接实现Lock
或ReadWriteLock
接口。 然而,StampedLock可以看作asReadLock()
, asWriteLock()
,或asReadWriteLock()
中,仅需要在一组相关联的功能的应用程序。
样品用法。 下面说明了一个维护简单二维点的类中的一些使用习语。 示例代码说明了一些try / catch约定,即使这些惯例在这里不是严格需要的,因为它们的身体中不会发生异常。
class Point { private double x, y; private final StampedLock sl = new StampedLock(); void move(double deltaX, double deltaY) { // an exclusively locked method long stamp = sl.writeLock(); try { x += deltaX; y += deltaY; } finally { sl.unlockWrite(stamp); } } double distanceFromOrigin() { // A read-only method long stamp = sl.tryOptimisticRead(); double currentX = x, currentY = y; if (!sl.validate(stamp)) { stamp = sl.readLock(); try { currentX = x; currentY = y; } finally { sl.unlockRead(stamp); } } return Math.sqrt(currentX * currentX + currentY * currentY); } void moveIfAtOrigin(double newX, double newY) { // upgrade // Could instead start with optimistic, not read mode long stamp = sl.readLock(); try { while (x == 0.0 && y == 0.0) { long ws = sl.tryConvertToWriteLock(stamp); if (ws != 0L) { stamp = ws; x = newX; y = newY; break; } else { sl.unlockRead(stamp); stamp = sl.writeLock(); } } } finally { sl.unlock(stamp); } } }
Constructor and Description |
---|
StampedLock()
创建一个新的锁,最初处于未锁定状态。
|
Modifier and Type | Method and Description |
---|---|
Lock |
asReadLock()
返回此StampedLock的一个简单的 Lock 视图,其中Lock.lock() 方法映射到readLock() ,并且类似地用于其他方法。
|
ReadWriteLock |
asReadWriteLock()
返回此StampedLock的 ReadWriteLock 视图,其中ReadWriteLock.readLock() 方法映射到asReadLock() ,ReadWriteLock.writeLock() 转换为asWriteLock() 。
|
Lock |
asWriteLock()
返回此StampedLock的一个简单的 Lock 视图,其中Lock.lock() 方法映射到writeLock() ,并且类似地用于其他方法。
|
int |
getReadLockCount()
查询为此锁持有的读取锁的数量。
|
boolean |
isReadLocked()
返回
true 如果锁当前是非排他地。
|
boolean |
isWriteLocked()
返回
true 如果锁当前是唯一的。
|
long |
readLock()
不排他地获取锁定,如有必要,阻塞。
|
long |
readLockInterruptibly()
非排他性地获取锁定,如有必要,阻塞,直到可用或当前线程中断。
|
String |
toString()
返回一个标识此锁的字符串以及其锁定状态。
|
long |
tryConvertToOptimisticRead(long stamp)
如果锁定状态符合给定的印记,则如果印记表示持有锁定,则释放它并返回观察印记。
|
long |
tryConvertToReadLock(long stamp)
如果锁定状态与给定的标记匹配,则执行以下操作之一。
|
long |
tryConvertToWriteLock(long stamp)
如果锁定状态与给定的标记匹配,则执行以下操作之一。
|
long |
tryOptimisticRead()
返回可以稍后验证的印记,如果专门锁定则返回零。
|
long |
tryReadLock()
非专门获取锁,如果它立即可用。
|
long |
tryReadLock(long time, TimeUnit unit)
如果在给定时间内可用,并且当前线程未被中断,则非排他性地获取锁。
|
boolean |
tryUnlockRead()
释放读锁定的一个保持位,如果保持,而不需要戳记值。
|
boolean |
tryUnlockWrite()
释放写入锁定,如果被保留,而不需要标记值。
|
long |
tryWriteLock()
专门获取锁,如果它立即可用。
|
long |
tryWriteLock(long time, TimeUnit unit)
如果在给定时间内可用,并且当前线程未被中断,则专门获取该锁。
|
void |
unlock(long stamp)
如果锁定状态与给定的标记匹配,则释放相应的锁定模式。
|
void |
unlockRead(long stamp)
如果锁定状态与给定的标记匹配,则释放非排他锁。
|
void |
unlockWrite(long stamp)
如果锁定状态与给定的邮票相匹配,则释放排他锁。
|
boolean |
validate(long stamp)
如果从发布给定邮票以来没有专门获取锁,则返回true。
|
long |
writeLock()
专门获取锁定,如有必要,阻塞。
|
long |
writeLockInterruptibly()
专门获取锁定,如有必要,阻塞,直到可用或当前线程中断。
|
public long writeLock()
public long tryWriteLock()
public long tryWriteLock(long time, TimeUnit unit) throws InterruptedException
Lock.tryLock(long,TimeUnit)
指定 。
time
- 等待锁的最长时间
unit
-
time
参数的时间单位
InterruptedException
- 如果当前线程在获取锁定之前中断
public long writeLockInterruptibly() throws InterruptedException
Lock.lockInterruptibly()
规定的行为 。
InterruptedException
- 如果当前线程在获取锁定之前中断
public long readLock()
public long tryReadLock()
public long tryReadLock(long time, TimeUnit unit) throws InterruptedException
Lock.tryLock(long,TimeUnit)
指定 。
time
- 等待锁的最长时间
unit
-
time
参数的时间单位
InterruptedException
- 如果当前线程在获取锁定之前中断
public long readLockInterruptibly() throws InterruptedException
Lock.lockInterruptibly()
规定的行为 。
InterruptedException
- 如果当前线程在获取锁之前中断
public long tryOptimisticRead()
public boolean validate(long stamp)
tryOptimisticRead()
获取的值或此锁定的锁定方法调用此方法没有定义的效果或结果。
stamp
- 邮票
true
如果锁定自发行给定邮票以来没有被专门获取;
否则假
public void unlockWrite(long stamp)
stamp
- 通过写锁操作返回的邮票
IllegalMonitorStateException
- 如果邮票与此锁的当前状态不匹配
public void unlockRead(long stamp)
stamp
- 通过读锁操作返回的邮票
IllegalMonitorStateException
- 如果邮票与此锁的当前状态不匹配
public void unlock(long stamp)
stamp
- 由锁定操作返回的邮票
IllegalMonitorStateException
- 如果邮票与此锁的当前状态不匹配
public long tryConvertToWriteLock(long stamp)
stamp
- 邮票
public long tryConvertToReadLock(long stamp)
stamp
- 邮票
public long tryConvertToOptimisticRead(long stamp)
stamp
- 邮票
public boolean tryUnlockWrite()
true
如果锁被保持,否则为false
public boolean tryUnlockRead()
true
,否则为false
public boolean isWriteLocked()
true
如果锁目前是唯一的。
true
如果锁目前是唯一的
public boolean isReadLocked()
true
如果锁当前非排他地。
true
如果锁当前是非排他性的
public int getReadLockCount()
public String toString()
"Unlocked"
或字符串"Write-locked"
或字符串"Read-locks:"
后跟当前持有的读锁定数。
public Lock asReadLock()
Lock
视图,其中Lock.lock()
方法映射到readLock()
,其他方法类似。
返回的Lock不支持Condition
;
方法Lock.newCondition()
抛出UnsupportedOperationException
。
public Lock asWriteLock()
Lock
视图,其中Lock.lock()
方法映射到writeLock()
,并且类似地用于其他方法。
返回的Lock不支持Condition
;
方法Lock.newCondition()
抛出UnsupportedOperationException
。
public ReadWriteLock asReadWriteLock()
ReadWriteLock
视图此StampedLock其中的ReadWriteLock.readLock()
方法被映射到asReadLock()
和ReadWriteLock.writeLock()
至asWriteLock()
。