- java.lang.Object
-
- java.util.concurrent.locks.StampedLock
-
- All Implemented Interfaces:
-
Serializable
public class StampedLock extends Object implements Serializable
一种基于能力的锁,具有三种模式用于控制读/写访问。 StampedLock的状态由版本和模式组成。 锁定采集方法返回一个表示和控制相对于锁定状态的访问的印记; 这些方法的“尝试”版本可能会返回特殊值为零以表示获取访问失败。 锁定释放和转换方法要求邮票作为参数,如果它们与锁的状态不匹配则失败。 这三种模式是:- 写作。 方法
writeLock()可能阻止等待独占访问,返回可以在方法unlockWrite(long)中使用的印记来释放锁定。 还提供了tryWriteLock未定义和定时版本。 当锁保持写入模式时,不能获得读取锁定,并且所有乐观读取验证都将失败。 - 读。 方法
readLock()可能阻止等待非独占访问,返回可以在方法unlockRead(long)中使用的印记来释放锁。 还提供了tryReadLock未定义和定时版本。 - 乐观阅读 方法
tryOptimisticRead()只有当锁当前未保持在写入模式时才返回非零标记。 方法validate(long)如果在获取给定的印记之后尚未在写入模式中获取锁,则返回true。 这种模式可以被认为是一个非常弱的版本的读锁,可以随时由作家打破。 对简单的只读代码段使用乐观模式通常会减少争用并提高吞吐量。 然而,其使用本质上是脆弱的。 乐观阅读部分只能读取字段并将其保存在局部变量中,以供后验证使用。 以乐观模式读取的字段可能会非常不一致,因此只有在熟悉数据表示以检查一致性和/或重复调用方法validate()时,使用情况才适用。 例如,当首次读取对象或数组引用,然后访问其字段,元素或方法之一时,通常需要这样的步骤。
此类还支持有条件地在三种模式下提供转换的方法。 例如,方法
tryConvertToWriteLock(long)尝试“升级”模式,如果(1)已经在书写模式(2)处于读取模式并且没有其他读取器或(3)处于乐观模式并且锁可用的情况下返回有效写入戳记。 这些方法的形式旨在帮助减少在基于重试的设计中出现的一些代码膨胀。StampedLocks设计用作线程安全组件开发中的内部实用程序。 他们的使用依赖于他们保护的数据,对象和方法的内部属性的知识。 它们不是可重入的,所以锁定的机构不应该调用其他可能尝试重新获取锁的未知方法(尽管您可以将戳记传递给可以使用或转换它的其他方法)。 读锁定模式的使用依赖于相关的代码段是无副作用的。 未经验证的乐观阅读部分不能调用不知道容忍潜在不一致的方法。 邮票使用有限表示,并且不是加密安全的(即,有效的邮票可能是可猜测的)。 邮票值可以在连续运行一年(不早于)之后回收。 不超过此期限使用或验证的邮票可能无法正确验证。 StampedLocks是可序列化的,但总是反序列化为初始解锁状态,因此它们对于远程锁定无用。
像
Semaphore一样,但与大多数Lock实现不同,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); } } }- 从以下版本开始:
- 1.8
- 另请参见:
- Serialized Form
-
-
构造方法摘要
构造方法 Constructor 描述 StampedLock()创建一个新的锁,最初处于未锁定状态。
-
方法摘要
所有方法 接口方法 具体的方法 Modifier and Type 方法 描述 LockasReadLock()返回此StampedLock的平面Lock视图,其中Lock.lock()方法映射到readLock(),对于其他方法也是如此。ReadWriteLockasReadWriteLock()返回此StampedLock的ReadWriteLock视图,其中ReadWriteLock.readLock()方法映射到asReadLock(),而ReadWriteLock.writeLock()映射到asWriteLock()。LockasWriteLock()返回此StampedLock的一个平面Lock视图,其中Lock.lock()方法映射到writeLock(),其他方法类似。intgetReadLockCount()查询为此锁持有的读取锁的数量。booleanisReadLocked()如果锁定当前非排他地,则返回true。booleanisWriteLocked()返回true如果锁目前是唯一的。longreadLock()不排他地获取锁定,如有必要,阻塞。longreadLockInterruptibly()非排他性地获取锁定,如有必要,阻塞,直到可用或当前线程中断。StringtoString()返回一个标识此锁的字符串以及其锁定状态。longtryConvertToOptimisticRead(long stamp)如果锁定状态与给定的印记相匹配,则原子地,如果印记表示持有锁定,则释放它并返回观察印记。longtryConvertToReadLock(long stamp)如果锁定状态与给定的标记匹配,则原子地执行以下操作之一。longtryConvertToWriteLock(long stamp)如果锁定状态与给定的标记匹配,则原子地执行以下操作之一。longtryOptimisticRead()返回可以稍后验证的印记,如果专门锁定则返回零。longtryReadLock()非专门获取锁,如果它立即可用。longtryReadLock(long time, TimeUnit unit)如果在给定时间内可用,并且当前线程未被中断,则非排他性地获取锁。booleantryUnlockRead()释放读锁定的一个保持位,如果保持,而不需要戳记值。booleantryUnlockWrite()释放写入锁定,如果被保留,而不需要标记值。longtryWriteLock()专门获取锁,如果它立即可用。longtryWriteLock(long time, TimeUnit unit)如果在给定时间内可用,并且当前线程未被中断,则专门获取该锁。voidunlock(long stamp)如果锁定状态与给定的标记匹配,则释放相应的锁定模式。voidunlockRead(long stamp)如果锁定状态与给定的标记匹配,则释放非排他锁。voidunlockWrite(long stamp)如果锁定状态与给定的邮票相匹配,则释放排他锁。booleanvalidate(long stamp)如果从发布给定邮票以来没有专门获取锁,则返回true。longwriteLock()专门获取锁定,如有必要,阻塞。longwriteLockInterruptibly()专门获取锁定,如有必要,阻塞,直到可用或当前线程中断。
-
-
-
方法详细信息
-
writeLock
public long writeLock()
专门获取锁定,如有必要,阻塞。- 结果
- 可用于解锁或转换模式的写印章
-
tryWriteLock
public long tryWriteLock()
专门获取锁,如果它立即可用。- 结果
- 可用于解锁或转换模式的写入戳记,如果锁定不可用,则为零
-
tryWriteLock
public long tryWriteLock(long time, TimeUnit unit) throws InterruptedException如果在给定时间内可用,并且当前线程未被中断,则专门获取该锁。 超时和中断下的行为匹配方法Lock.tryLock(long,TimeUnit)。- 参数
-
time- 等待锁的最长时间 -
unit-time参数的时间单位 - 结果
- 可用于解锁或转换模式的写入戳记,如果锁定不可用,则为零
- 异常
-
InterruptedException- 如果当前线程在获取锁定之前中断
-
writeLockInterruptibly
public long writeLockInterruptibly() throws InterruptedException专门获取锁定,如有必要,阻塞,直到可用或当前线程中断。 中断行为符合方法Lock.lockInterruptibly()规定的行为 。- 结果
- 可用于解锁或转换模式的写印章
- 异常
-
InterruptedException- 如果当前线程在获取锁定之前中断
-
readLock
public long readLock()
不排他地获取锁定,如有必要,阻塞。- 结果
- 一个可用于解锁或转换模式的读印
-
tryReadLock
public long tryReadLock()
非专门获取锁,如果它立即可用。- 结果
- 可用于解锁或转换模式的读取戳记,如果锁定不可用,则为零
-
tryReadLock
public long tryReadLock(long time, TimeUnit unit) throws InterruptedException如果在给定时间内可用,并且当前线程未被中断,则非排他性地获取锁。 超时和中断下的行为匹配方法Lock.tryLock(long,TimeUnit)指定。- 参数
-
time- 等待锁的最长时间 -
unit-time参数的时间单位 - 结果
- 可用于解锁或转换模式的读取戳记,如果锁定不可用,则为零
- 异常
-
InterruptedException- 如果当前线程在获取锁定之前中断
-
readLockInterruptibly
public long readLockInterruptibly() throws InterruptedException非排他性地获取锁定,如有必要,阻塞,直到可用或当前线程中断。 中断行为符合方法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- 邮票 - 结果
- 有效的读取戳记,或失败时为零
-
tryConvertToOptimisticRead
public long tryConvertToOptimisticRead(long stamp)
如果锁定状态与给定的印记相匹配,则原子地,如果印记表示持有锁定,则释放它并返回观察印记。 或者,如果乐观阅读,如果验证返回。 在所有其他情况下,此方法返回零,因此可能作为“tryUnlock”的形式有用。- 参数
-
stamp- 邮票 - 结果
- 有效的乐观阅读印记,或失败时为零
-
tryUnlockWrite
public boolean tryUnlockWrite()
释放写入锁定,如果被保留,而不需要标记值。 此方法可能对错误后的恢复有用。- 结果
-
如果锁定是
true,否则为false
-
tryUnlockRead
public boolean tryUnlockRead()
释放读锁定的一个保持位,如果保持,而不需要戳记值。 此方法可能对错误后的恢复有用。- 结果
-
true如果读取锁定,否则为false
-
isWriteLocked
public boolean isWriteLocked()
如果锁当前仅被true则返回true。- 结果
-
true如果锁当前是唯一的
-
isReadLocked
public boolean isReadLocked()
如果锁定当前非排他地,则返回true。- 结果
-
true如果锁当前是非排他地
-
getReadLockCount
public int getReadLockCount()
查询为此锁持有的读取锁的数量。 该方法设计用于监控系统状态,不用于同步控制。- 结果
- 持有的读取锁的数量
-
toString
public String toString()
返回一个标识此锁的字符串以及其锁定状态。 括号中的状态包括字符串"Unlocked"或字符串"Write-locked"或字符串"Read-locks:"后跟当前持有的读锁定数。
-
asReadLock
public Lock asReadLock()
返回此StampedLock的Lock视图,其中Lock.lock()方法映射到readLock(),其他方法类似。 返回的Lock不支持Condition; 方法Lock.newCondition()抛出UnsupportedOperationException。- 结果
- 锁
-
asWriteLock
public Lock asWriteLock()
返回此StampedLock的一个简单的Lock视图,其中Lock.lock()方法映射到writeLock(),并且类似于其他方法。 返回的Lock不支持Condition; 方法Lock.newCondition()抛出UnsupportedOperationException。- 结果
- 锁
-
asReadWriteLock
public ReadWriteLock asReadWriteLock()
返回一个ReadWriteLock视图此StampedLock的其中ReadWriteLock.readLock()方法被映射到asReadLock(),和ReadWriteLock.writeLock()到asWriteLock()。- 结果
- the lock
-
-