• AQS:AbstractQueuedSynchronize类


    AbstractQueuedSynchronize 抽象队列同步器 类:

    简介:

    -提供了一个框架来实现阻塞锁和依赖先进先出(FIFO:first-in-first-out)等待对列的相关同步器(信号量、事件等)

     此类被设计为对大多数依赖单原子 int 值来表示状态的同步器来说非常有用,子类必须定义那些 改变状态 以及 定义该状态对于被获取或释放有意义的protected方法

     鉴于此,此类的其他方法执行所有队列和阻塞机制

    -子类可以维护其他状态字段,到那时只能原子更新 int 值通过使用方法getState、setState、compareAndSetState来跟踪于遵守同步器

      子类应该定义non-public的内部类帮助器,用于实现其封闭类的同步属性,AbstractQueuedSynchronize不实现任何同步接口,相反他定义了像acquireInterruptible这样的方法,

      可以被具体的 锁 和相关同步器作为适当的调用实现他们的公共方法

    -该类默认支持独占和共享模式:以独占模式获取时,其他线程尝试获取操作无法成功;共享模式被多个线程获取可能(但不一定)成功

     除了机械意义上的差异,当共享模式获取成功时,下一个等待线程也许确定它是否也可以获取成功,在不同的模式下等待的线程共享相同的FIFO queue

     通常子类只支持其中一种模式,但是两种模式都可以发挥作用,例如:ReadWriteLock中。只支持其中一种模式的不需实现另一种未使用的模式

    -该类定义了一个嵌套类:ConditionObject,通过子类支持排他模式,可以作为Condition使用

     方法release使用当前getState值调用,完全释放这个对象,并且acquire方法给定这个保存的状态值,最终这个对象恢复到他以前获取得的状态

     没有AQS方法创建这样一个条件,所以不满足这个约束,不要使用它。ConditionObject的行为取决于他的同步器实现的语义

    -该类作为内部queue提供检查、检测、和监视方法,以及conditionObject对象提供类似的方法。可以根据使用AQS将他们导出到类中,使用他们的同步机制

    -该类的序列化只存储底层原子int维护状态,因为反序列化对象具有空队列,需要序列化典型的子类定义一个readObject方法,该方法在反序列化时将还原为已知的初始状态

    - 使用

      要使用此类作为同步器的基础,可以使用getState、setState、compareAndSetState检查和修改同步状态,从而根据需要重新定义以下方法

      tryAcquire、tryRelease、tryAcquireShared、tryReleaseShared、isHeldExclusively

     默认情况每个方法都会抛出UnsupportedOperationException。这些方法的实现必须是线程内部安全,通常很短且不阻塞,定义这些方法是只支持使用此类的方法,其他方法都是final声明,因为他们不支持独立更改。独立继承AbstractOwnableSynchronize的方法对跟踪拥有独占同步器的线程非常有用,建议使用他们作为监视和诊断工具帮助用户确定哪些线程持有锁

    -即使该类基于内部FIFO的queue,他也不会自动执行FIFO获取策略,胡吃同步的核心形式为:

    Acquire:
    * while (!tryAcquire(arg)) {
    * <em>如果线程尚未排队,将其加入队列</em>;
    * <em>可能阻塞当前线程</em>;
    * }
    *
    Release:
    * if (tryRelease(arg))
    * <em>解除第一个排队线程的阻塞</em>;
    共享模式类似,不过可能涉及到级联信号

    - 因为acquire的检查是在排队前调用,所以一个新的acquire请求线程可能先于其他被阻塞排队的线程之前成功,不过如果有需要可以通过内部调用一个或多个检查方法如:tryAcquire、tryAcquireShared来禁止乱序驳船,从而提供一个fair公平的FIFO 请求。特别:大多数公平同步器可以定义tryAcquire返回false如果hashQueuedPredecessors(一个特被为公平锁定义的方法)返回ture时 ,其他情况也是可以的

    -吞吐性和伸缩性通常在默认插队(barging)(也称为:贪心greedy、非公平renouncement、避免结队convoy-avoidance)策略中最高,虽然这不能保证是公平的或无饥饿的,但是允许较早排队的线程在较晚排队的线程之前重新竞争,每次重新竞争都有无偏倚的机会对传入的线程成功。此外,当acquires不自旋,通常意义上,他们可以执行多次调用tryAcquire并在阻塞之前插入其他计算。当独占同步只是暂时的持有,这就提供了自旋的大部分好处,当独占同步不持有时,则没有这部分责任。如果需要,可以通过前面的调用增强这一功能,以获取带有“快速通道”的检查方法,可能需要预先检查hashCodition/hashQueuedThreads,只有在同步器可能不存在竞争时才这样做

    -这个类为同步提供了一个高效和可伸缩的基础,部分方法时通过将他的使用范围专门化为依赖int 状态acquire和release参数以及一个内部FIFO队列的同步器,如果这些不够时,可以使用较低级别的atomic类构建同步器,可以自己定义Queue和LockSupport阻塞支持

    -使用案例:

  • 相关阅读:
    演示使用string对象(续)
    P2216 [HAOI2007]理想的正方形 单调队列
    SP1805 HISTOGRA
    P4556 [Vani有约会]雨天的尾巴 树链剖分 线段树合并
    codeforces 600E 线段树合并
    HDU2197 本原串
    P3806 【模板】点分治1
    牛客10 Popping Balloons
    P3261 [JLOI2015]城池攻占 左偏树
    P4549 【模板】裴蜀定理
  • 原文地址:https://www.cnblogs.com/gsanye/p/11192166.html
Copyright © 2020-2023  润新知