- 所有已实现的接口:
Serializable
- 写作。方法
writeLock()可能会阻塞等待独占访问,返回一个可以在方法unlockWrite(long)中使用的标记来释放锁。还提供了tryWriteLock的非定时和定时版本。当锁处于写入模式时,可能无法获得读取锁,并且所有乐观读取验证都将失败。 - 阅读。方法
readLock()可能会阻塞等待非独占访问,返回一个可以在方法unlockRead(long)中使用的标记来释放锁。还提供了tryReadLock的非定时和定时版本。 - 乐观的阅读。方法
tryOptimisticRead()仅当锁定当前未处于写入模式时才返回非零标记。如果在获得给定标记后未在写模式下获取锁,则方法validate(long)返回 true,在这种情况下,在调用tryOptimisticRead之后,最近一次写锁释放之前的所有操作都发生在操作之前。这种模式可以被认为是一个非常弱的读锁版本,可以随时被写入者破坏。对短的只读代码段使用乐观读取模式通常可以减少争用并提高吞吐量。然而,它的使用本质上是脆弱的。乐观读取部分应该只读取字段并将它们保存在局部变量中以供以后在验证后使用。在乐观读取模式下读取的字段可能非常不一致,因此仅当您足够熟悉数据表示以检查一致性和/或重复调用方法validate()时才适用。例如,当首先读取对象或数组引用,然后访问其字段、元素或方法之一时,通常需要执行此类步骤。
此类还支持有条件地提供跨三种模式的转换的方法。例如,方法 tryConvertToWriteLock(long) 尝试“升级”模式,如果(1)已经处于写入模式(2)处于读取模式并且没有其他读者或(3)处于乐观读取模式并且锁定是,则返回有效的写入标记可用的。这些方法的形式旨在帮助减少在基于重试的设计中否则会出现的一些代码膨胀。
StampedLocks 设计用作线程安全组件开发中的内部实用程序。它们的使用依赖于对它们所保护的数据、对象和方法的内部属性的了解。它们是不可重入的,因此锁定的主体不应调用其他可能尝试重新获取锁的未知方法(尽管您可以将戳记传递给可以使用或转换它的其他方法)。读取锁定模式的使用依赖于没有副作用的相关代码段。未经验证的乐观读取部分无法调用已知无法容忍潜在不一致的方法。邮票使用有限的表示,并且不是加密安全的(即,一个有效的邮票可能是可猜测的)。邮票值可以在(不早于)连续运行一年后回收。超过此期限而未使用或验证的邮票可能无法正确验证。 StampedLocks 是可序列化的,但总是反序列化为初始解锁状态,因此它们对远程锁定没有用。
与 Semaphore 一样,但与大多数 Lock 实现不同,StampedLocks 没有所有权的概念。在一个线程中获取的锁可以在另一个线程中释放或转换。
StampedLock 的调度策略并不总是优先于读者而不是作者,反之亦然。所有“尝试”方法都是尽力而为,不一定符合任何调度或公平策略。任何获取或转换锁的“try”方法的零返回不携带任何关于锁状态的信息;后续调用可能会成功。
因为它支持跨多种锁模式的协调使用,所以这个类不直接实现Lock 或ReadWriteLock 接口。但是,在仅需要相关功能集的应用程序中,可以查看 StampedLock asReadLock() 、asWriteLock() 或 asReadWriteLock() 。
内存同步。在任何模式下成功锁定效果的方法与 Lock 操作具有相同的内存同步效果,如第 17 章所述Java 语言规范.在写入模式下成功解锁的方法与 Unlock 操作具有相同的内存同步效果。在乐观读取用法中,只有在稍后的验证返回 true 时,保证在最近的写入模式解锁操作之前发生的操作先于 tryOptimisticRead 之后的操作;否则无法保证 tryOptimisticRead 和 validate 之间的读取获得一致的快照。
示例用法。下面举例说明维护简单二维点的类中的一些用法习语。示例代码说明了一些 try/catch 约定,尽管这里并不严格需要它们,因为它们的主体中不会出现异常。
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
// an exclusively locked method
void move(double deltaX, double deltaY) {
long stamp = sl.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlockWrite(stamp);
}
}
// a read-only method
// upgrade from optimistic read to read lock
double distanceFromOrigin() {
long stamp = sl.tryOptimisticRead();
try {
retryHoldingLock: for (;; stamp = sl.readLock()) {
if (stamp == 0L)
continue retryHoldingLock;
// possibly racy reads
double currentX = x;
double currentY = y;
if (!sl.validate(stamp))
continue retryHoldingLock;
return Math.hypot(currentX, currentY);
}
} finally {
if (StampedLock.isReadLockStamp(stamp))
sl.unlockRead(stamp);
}
}
// upgrade from optimistic read to write lock
void moveIfAtOrigin(double newX, double newY) {
long stamp = sl.tryOptimisticRead();
try {
retryHoldingLock: for (;; stamp = sl.writeLock()) {
if (stamp == 0L)
continue retryHoldingLock;
// possibly racy reads
double currentX = x;
double currentY = y;
if (!sl.validate(stamp))
continue retryHoldingLock;
if (currentX != 0.0 || currentY != 0.0)
break;
stamp = sl.tryConvertToWriteLock(stamp);
if (stamp == 0L)
continue retryHoldingLock;
// exclusive access
x = newX;
y = newY;
return;
}
} finally {
if (StampedLock.isWriteLockStamp(stamp))
sl.unlockWrite(stamp);
}
}
// upgrade read lock to write lock
void moveIfAtOrigin2(double newX, double newY) {
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);
}
}
}
- 看Java 语言规范:
-
17.4 内存模型
- 自从:
- 1.8
- 参见:
-
构造方法总结
构造方法 -
方法总结
修饰符和类型方法描述返回此 StampedLock 的ReadWriteLock视图,其中ReadWriteLock.readLock()方法映射到asReadLock(),ReadWriteLock.writeLock()映射到asWriteLock()。int查询为此锁持有的读取锁的数量。static booleanisLockStamp(long stamp) 告诉邮票是否代表持有锁。static booleanisOptimisticReadStamp(long stamp) 告诉邮票是否代表成功的乐观阅读。boolean如果锁当前是非独占持有的,则返回true。static booleanisReadLockStamp(long stamp) 告诉邮票是否代表非独占地持有锁。boolean如果锁当前以独占方式持有,则返回true。static booleanisWriteLockStamp(long stamp) 告诉邮票是否代表独占锁。longreadLock()非独占地获取锁,必要时阻塞直到可用。long非独占地获取锁,必要时阻塞直到可用或当前线程被中断。toString()返回标识此锁及其锁定状态的字符串。longtryConvertToOptimisticRead(long stamp) 如果锁定状态与给定的戳记匹配,则原子地,如果该戳记表示持有锁,则释放它并返回一个观察戳记。longtryConvertToReadLock(long stamp) 如果锁定状态与给定的标记匹配,则自动执行以下操作之一。longtryConvertToWriteLock(long stamp) 如果锁定状态与给定的标记匹配,则自动执行以下操作之一。long返回一个稍后可以验证的戳记,如果完全锁定则返回零。long如果锁立即可用,则非独占地获取锁。longtryReadLock(long time, TimeUnit unit) 如果在给定时间内可用且当前线程未被中断,则非独占获取锁。boolean释放一个读锁(如果持有),而不需要标记值。boolean释放写锁(如果持有),而不需要标记值。long如果锁立即可用,则以独占方式获取锁。longtryWriteLock(long time, TimeUnit unit) 如果在给定时间内可用且当前线程未被中断,则独占获取锁。voidunlock(long stamp) 如果锁定状态与给定的标记匹配,则释放锁定的相应模式。voidunlockRead(long stamp) 如果锁定状态与给定的标记匹配,则释放非排他锁。voidunlockWrite(long stamp) 如果锁定状态与给定的标记匹配,则释放独占锁。booleanvalidate(long stamp) 如果自给定戳记发行以来尚未独占获取锁,则返回 true。long独占获取锁,必要时阻塞直到可用。long独占获取锁,必要时阻塞,直到可用或当前线程被中断。
-
构造方法详细信息
-
StampedLock
public StampedLock()创建一个新锁,最初处于解锁状态。
-
-
方法详情
-
writeLock
public long writeLock()独占获取锁,必要时阻塞直到可用。- 返回:
- 可用于解锁或转换模式的写入标记
-
tryWriteLock
public long tryWriteLock()如果锁立即可用,则以独占方式获取锁。- 返回:
- 可用于解锁或转换模式的写入戳记,如果锁不可用则为零
-
tryWriteLock
如果在给定时间内可用且当前线程未被中断,则独占获取锁。超时和中断下的行为与为方法Lock.tryLock(long,TimeUnit)指定的行为相匹配。- 参数:
time- 等待锁的最长时间unit-time参数的时间单位- 返回:
- 可用于解锁或转换模式的写入戳记,如果锁不可用则为零
- 抛出:
InterruptedException- 如果当前线程在获取锁之前被中断
-
writeLockInterruptibly
独占获取锁,必要时阻塞,直到可用或当前线程被中断。中断下的行为与为方法Lock.lockInterruptibly()指定的行为相匹配。- 返回:
- 可用于解锁或转换模式的写入标记
- 抛出:
InterruptedException- 如果当前线程在获取锁之前被中断
-
readLock
public long readLock()非独占地获取锁,必要时阻塞直到可用。- 返回:
- 可用于解锁或转换模式的已读标记
-
tryReadLock
public long tryReadLock()如果锁立即可用,则非独占地获取锁。- 返回:
- 可用于解锁或转换模式的读取标记,如果锁不可用则为零
-
tryReadLock
如果在给定时间内可用且当前线程未被中断,则非独占获取锁。超时和中断下的行为与为方法Lock.tryLock(long,TimeUnit)指定的行为相匹配。- 参数:
time- 等待锁的最长时间unit-time参数的时间单位- 返回:
- 可用于解锁或转换模式的读取标记,如果锁不可用则为零
- 抛出:
InterruptedException- 如果当前线程在获取锁之前被中断
-
readLockInterruptibly
非独占地获取锁,必要时阻塞直到可用或当前线程被中断。中断下的行为与为方法Lock.lockInterruptibly()指定的行为相匹配。- 返回:
- 可用于解锁或转换模式的已读标记
- 抛出:
InterruptedException- 如果当前线程在获取锁之前被中断
-
tryOptimisticRead
public long tryOptimisticRead()返回一个稍后可以验证的戳记,如果完全锁定则返回零。- 返回:
- 有效的乐观读取标记,如果完全锁定则为零
-
validate
public boolean validate(long stamp) 如果自给定戳记发行以来尚未独占获取锁,则返回 true。如果标记为零,则始终返回 false。如果标记表示当前持有的锁,则始终返回 true。使用未从tryOptimisticRead()获得的值或此锁的锁定方法调用此方法没有定义的效果或结果。- 参数:
stamp- 邮票- 返回:
true如果自给定印章发行以来尚未独占获取锁;否则为假
-
unlockWrite
public void unlockWrite(long stamp) 如果锁定状态与给定的标记匹配,则释放独占锁。- 参数:
stamp- 写锁操作返回的标记- 抛出:
IllegalMonitorStateException- 如果戳记与此锁的当前状态不匹配
-
unlockRead
public void unlockRead(long stamp) 如果锁定状态与给定的标记匹配,则释放非排他锁。- 参数:
stamp- 读锁操作返回的标记- 抛出:
IllegalMonitorStateException- 如果戳记与此锁的当前状态不匹配
-
unlock
public void unlock(long stamp) 如果锁定状态与给定的标记匹配,则释放锁定的相应模式。- 参数:
stamp- 锁定操作返回的标记- 抛出:
IllegalMonitorStateException- 如果戳记与此锁的当前状态不匹配
-
tryConvertToWriteLock
public long tryConvertToWriteLock(long stamp) 如果锁定状态与给定的标记匹配,则自动执行以下操作之一。如果戳记表示持有写锁,则返回它。或者,如果是读锁,如果写锁可用,则释放读锁并返回一个写戳。或者,如果是乐观读取,则仅在立即可用时才返回写入标记。在所有其他情况下,此方法返回零。- 参数:
stamp- 邮票- 返回:
- 有效的写戳记,或失败时为零
-
tryConvertToReadLock
public long tryConvertToReadLock(long stamp) 如果锁定状态与给定的标记匹配,则自动执行以下操作之一。如果stamp表示持有写锁,则释放并获得读锁。或者,如果是读锁,则返回它。或者,如果是乐观读取,则获取读取锁并仅在立即可用时才返回读取标记。在所有其他情况下,此方法返回零。- 参数:
stamp- 邮票- 返回:
- 有效的读取标记,或失败时为零
-
tryConvertToOptimisticRead
public long tryConvertToOptimisticRead(long stamp) 如果锁定状态与给定的戳记匹配,则原子地,如果该戳记表示持有锁,则释放它并返回一个观察戳记。或者,如果是乐观读取,则在验证后返回它。此方法在所有其他情况下返回零,因此作为“tryUnlock”的一种形式可能很有用。- 参数:
stamp- 邮票- 返回:
- 有效的乐观阅读标记,或失败时为零
-
tryUnlockWrite
public boolean tryUnlockWrite()释放写锁(如果持有),而不需要标记值。此方法可能对错误后的恢复很有用。- 返回:
true如果持有锁,否则为 false
-
tryUnlockRead
public boolean tryUnlockRead()释放一个读锁(如果持有),而不需要标记值。此方法可能对错误后的恢复很有用。- 返回:
true如果持有读锁,否则为假
-
isWriteLocked
public boolean isWriteLocked()如果锁当前以独占方式持有,则返回true。- 返回:
true如果锁当前是独占持有的
-
isReadLocked
public boolean isReadLocked()如果锁当前是非独占持有的,则返回true。- 返回:
true如果锁当前是非独占持有的
-
isWriteLockStamp
public static boolean isWriteLockStamp(long stamp) 告诉邮票是否代表独占锁。此方法可能与tryConvertToWriteLock(long)结合使用,例如:long stamp = sl.tryOptimisticRead(); try { ... stamp = sl.tryConvertToWriteLock(stamp); ... } finally { if (StampedLock.isWriteLockStamp(stamp)) sl.unlockWrite(stamp); }- 参数:
stamp- 由先前的 StampedLock 操作返回的戳记- 返回:
true如果标记是由成功的写锁定操作返回的- 自从:
- 10
-
isReadLockStamp
public static boolean isReadLockStamp(long stamp) 告诉邮票是否代表非独占地持有锁。此方法可能与tryConvertToReadLock(long)结合使用,例如:long stamp = sl.tryOptimisticRead(); try { ... stamp = sl.tryConvertToReadLock(stamp); ... } finally { if (StampedLock.isReadLockStamp(stamp)) sl.unlockRead(stamp); }- 参数:
stamp- 由先前的 StampedLock 操作返回的戳记- 返回:
true如果标记是由成功的读锁定操作返回的- 自从:
- 10
-
isLockStamp
public static boolean isLockStamp(long stamp) 告诉邮票是否代表持有锁。此方法可能与tryConvertToReadLock(long)和tryConvertToWriteLock(long)结合使用,例如:long stamp = sl.tryOptimisticRead(); try { ... stamp = sl.tryConvertToReadLock(stamp); ... stamp = sl.tryConvertToWriteLock(stamp); ... } finally { if (StampedLock.isLockStamp(stamp)) sl.unlock(stamp); }- 参数:
stamp- 由先前的 StampedLock 操作返回的戳记- 返回:
true如果标记是由成功的读锁或写锁操作返回的- 自从:
- 10
-
isOptimisticReadStamp
public static boolean isOptimisticReadStamp(long stamp) 告诉邮票是否代表成功的乐观阅读。- 参数:
stamp- 由先前的 StampedLock 操作返回的戳记- 返回:
true如果标记是由成功的乐观读取操作返回的,即来自tryOptimisticRead()或tryConvertToOptimisticRead(long)的非零返回- 自从:
- 10
-
getReadLockCount
public int getReadLockCount()查询为此锁持有的读取锁的数量。此方法设计用于监视系统状态,而不用于同步控制。- 返回:
- 持有读锁的数量
-
toString
返回标识此锁及其锁定状态的字符串。括号中的状态包括字符串"Unlocked"或字符串"Write-locked"或字符串"Read-locks:"后跟当前持有的读锁数。 -
asReadLock
返回此 StampedLock 的普通Lock视图,其中Lock.lock()方法映射到readLock(),其他方法也类似。返回的 Lock 不支持Condition;方法Lock.newCondition()抛出UnsupportedOperationException。- 返回:
- 锁
-
asWriteLock
返回此 StampedLock 的普通Lock视图,其中Lock.lock()方法映射到writeLock(),其他方法也类似。返回的 Lock 不支持Condition;方法Lock.newCondition()抛出UnsupportedOperationException。- 返回:
- 锁
-
asReadWriteLock
返回此 StampedLock 的ReadWriteLock视图,其中ReadWriteLock.readLock()方法映射到asReadLock(),ReadWriteLock.writeLock()映射到asWriteLock()。- 返回:
- 锁
-