Module  java.base

Class 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”方法的零返回不携带关于锁的状态的任何信息; 随后的调用可能会成功。

    因为它支持跨多种锁定模式的协调使用,所以该类不直接实现LockReadWriteLock接口。 然而,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
    • 构造方法详细信息

      • StampedLock

        public StampedLock​()
        创建一个新的锁,最初处于未锁定状态。
    • 方法详细信息

      • 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:"后跟当前持有的读锁定数。
        重写:
        toStringObject
        结果
        标识此锁的字符串以及其锁定状态