Share via


AbstractQueuedSynchronizer 类

定义

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

[Android.Runtime.Register("java/util/concurrent/locks/AbstractQueuedSynchronizer", DoNotGenerateAcw=true)]
public abstract class AbstractQueuedSynchronizer : Java.Util.Concurrent.Locks.AbstractOwnableSynchronizer, IDisposable, Java.Interop.IJavaPeerable
[<Android.Runtime.Register("java/util/concurrent/locks/AbstractQueuedSynchronizer", DoNotGenerateAcw=true)>]
type AbstractQueuedSynchronizer = class
    inherit AbstractOwnableSynchronizer
    interface ISerializable
    interface IJavaObject
    interface IDisposable
    interface IJavaPeerable
继承
AbstractQueuedSynchronizer
属性
实现

注解

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。 此类旨在成为大多数依赖于单个原子 int 值来表示状态的同步器的有用基础。 子类必须定义更改此状态的受保护方法,以及定义该状态在获取或释放对象方面的含义。 鉴于这些,此类中的其他方法执行所有排队和阻塞机制。 子类可以维护其他状态字段,但只有使用 方法 #getState操作的原子更新int值,#setState并且#compareAndSetState会跟踪同步。

子类应定义为用于实现其封闭类的同步属性的非公共内部帮助程序类。 类 AbstractQueuedSynchronizer 不实现任何同步接口。 相反,它定义了等 #acquireInterruptibly 方法,具体锁和相关同步器可以根据需要调用这些方法来实现其公共方法。

此类支持或同时支持默认<的 em>独占</em> 模式和<共享><模式>。 在独占模式下获取时,其他线程尝试获取的操作无法成功。 由多个线程获取的共享模式可能会 (,但不需要) 成功。 此类不 "了解&商;除了从机械意义上说,当共享模式成功获取时,下一个等待线程 (如果存在) 也必须确定它是否可以获取。 在不同模式下等待的线程共享同一 FIFO 队列。 通常,实现子类仅支持其中一种模式,但两者都可以发挥作用,例如 在 中 ReadWriteLock。 仅支持独占模式或仅共享模式的子类不需要定义支持未使用模式的方法。

此类定义一个嵌套ConditionObject类,该类可由支持独占模式的子类用作实现,该方法#isHeldExclusively报告是否针对当前线程进行独占同步,使用当前#getState值调用的方法#release将完全释放此对象,并在#acquire给定此保存的状态值的情况下,最终将此对象还原到其以前获取Condition的状态。 否则,没有 AbstractQueuedSynchronizer 方法会创建此类条件,因此,如果无法满足此约束,请不要使用它。 的行为 ConditionObject 当然取决于其同步器实现的语义。

此类为内部队列提供检查、检测和监视方法,并为条件对象提供类似的方法。 这些可以根据需要导出到类中, AbstractQueuedSynchronizer 使用 进行同步机制。

此类的序列化仅存储基础原子整数维护状态,因此反序列化的对象具有空线程队列。 需要可序列化性的典型子类将定义一个 readObject 方法,该方法在反序列化时将它还原到已知的初始状态。

<h2>用法</h2>

若要将此类用作同步器的基础,请通过使用 、 #setState 和/或 #compareAndSetState检查和/或修改同步状态#getState,重新定义以下方法(如果适用):

<ul><li>#tryAcquire<li>#tryRelease<li>#tryAcquireShared<li li><>#tryReleaseShared<#isHeldExclusively/ul>

默认情况下,这些方法中的每一个都会 UnsupportedOperationException引发 。 这些方法的实现必须在内部线程安全,并且通常应简短,而不是阻塞。 定义这些方法是<使用此类的仅限< em>/em> 支持的方法。 声明所有其他方法, final 因为它们不能独立变化。

还可以发现,从 AbstractOwnableSynchronizer 继承的方法可用于跟踪拥有独占同步器的线程。 建议使用它们 -- 这将启用监视和诊断工具来帮助用户确定哪些线程持有锁。

即使此类基于内部 FIFO 队列,它也不会自动强制实施 FIFO 获取策略。 独占同步的核心采用以下形式:

<em>Acquire:</em>
                while (!tryAcquire(arg)) {
<em>enqueue thread if it is not already queued</em>;
<em>possibly block current thread</em>;
                }

<em>Release:</em>
                if (tryRelease(arg))
<em>unblock the first queued thread</em>;

(共享模式类似,但可能涉及级联信号。)

<p id=“barging”>由于获取签入是在排队前调用的,因此新获取线程可能<<>>比阻塞和排队的其他线程早于其他线程。 但是,如果需要,可以通过在内部调用一个或多个检查方法来定义tryAcquire和/或tryAcquireShared禁用栏,从而提供<>公平</em> FIFO 获取顺序。 具体而言,如果 #hasQueuedPredecessors (专门设计为由false公平同步器使用的方法) 返回 ,则大多数公平同步器都可以定义为tryAcquire返回 true。 可能存在其他变体。

对于默认栏 (也称为 <em greedy</em>、<em>renouncement</em> 和 em>convoy-avoidance</>em>) 策略,吞吐量和<可伸缩性通常最高。 虽然这不能保证公平或无饥饿,但允许先于排队的线程在稍后排队的线程之前重新进行重新协调,并且每次重新协调都有针对传入线程成功的机会。 此外,虽然获取 不 &商;spin"从通常的意义上说,它们可能会在阻塞之前执行与其他计算交错的多次调用 tryAcquire 。 当独占同步只是短暂保留时,这提供了旋转的大部分好处,而没有进行独占同步时没有大部分责任。 如果需要,可以通过之前调用 来获取具有“快速路径”检查的方法(可能进行预检查 #hasContended 和/或 #hasQueuedThreads 仅在同步器可能不争用的情况下)来增强这一点。

此类通过将其使用范围专用于依赖于 int 状态、获取和释放参数以及内部 FIFO 等待队列的同步器,为同步提供高效且可缩放的基础。 如果这还不够,可以使用类、你自己的自定义java.util.Queue类和LockSupport阻止支持从较低级别java.util.concurrent.atomic atomic生成同步器。

<h2>用法示例</h2>

下面是一个不可重入的互斥锁类,该类使用值 0 表示解锁状态,使用值 0 表示锁定状态。 虽然非可重入锁并不严格要求记录当前所有者线程,但此类会这样做,以使使用情况更易于监视。 它还支持条件并公开一些检测方法:

{@code
            class Mutex implements Lock, java.io.Serializable {

              // Our internal helper class
              private static class Sync extends AbstractQueuedSynchronizer {
                // Acquires the lock if state is zero
                public boolean tryAcquire(int acquires) {
                  assert acquires == 1; // Otherwise unused
                  if (compareAndSetState(0, 1)) {
                    setExclusiveOwnerThread(Thread.currentThread());
                    return true;
                  }
                  return false;
                }

                // Releases the lock by setting state to zero
                protected boolean tryRelease(int releases) {
                  assert releases == 1; // Otherwise unused
                  if (!isHeldExclusively())
                    throw new IllegalMonitorStateException();
                  setExclusiveOwnerThread(null);
                  setState(0);
                  return true;
                }

                // Reports whether in locked state
                public boolean isLocked() {
                  return getState() != 0;
                }

                public boolean isHeldExclusively() {
                  // a data race, but safe due to out-of-thin-air guarantees
                  return getExclusiveOwnerThread() == Thread.currentThread();
                }

                // Provides a Condition
                public Condition newCondition() {
                  return new ConditionObject();
                }

                // Deserializes properly
                private void readObject(ObjectInputStream s)
                    throws IOException, ClassNotFoundException {
                  s.defaultReadObject();
                  setState(0); // reset to unlocked state
                }
              }

              // The sync object does all the hard work. We just forward to it.
              private final Sync sync = new Sync();

              public void lock()              { sync.acquire(1); }
              public boolean tryLock()        { return sync.tryAcquire(1); }
              public void unlock()            { sync.release(1); }
              public Condition newCondition() { return sync.newCondition(); }
              public boolean isLocked()       { return sync.isLocked(); }
              public boolean isHeldByCurrentThread() {
                return sync.isHeldExclusively();
              }
              public boolean hasQueuedThreads() {
                return sync.hasQueuedThreads();
              }
              public void lockInterruptibly() throws InterruptedException {
                sync.acquireInterruptibly(1);
              }
              public boolean tryLock(long timeout, TimeUnit unit)
                  throws InterruptedException {
                return sync.tryAcquireNanos(1, unit.toNanos(timeout));
              }
            }}

下面是类似于 的闩锁类 java.util.concurrent.CountDownLatch CountDownLatch ,只不过它只需要一 signal 个来触发。 由于闩锁是非独占的 shared ,因此它使用获取和释放方法。

{@code
            class BooleanLatch {

              private static class Sync extends AbstractQueuedSynchronizer {
                boolean isSignalled() { return getState() != 0; }

                protected int tryAcquireShared(int ignore) {
                  return isSignalled() ? 1 : -1;
                }

                protected boolean tryReleaseShared(int ignore) {
                  setState(1);
                  return true;
                }
              }

              private final Sync sync = new Sync();
              public boolean isSignalled() { return sync.isSignalled(); }
              public void signal()         { sync.releaseShared(1); }
              public void await() throws InterruptedException {
                sync.acquireSharedInterruptibly(1);
              }
            }}

在 1.5 中添加。

java.util.concurrent.locks.AbstractQueuedSynchronizerJava 文档。

此页面的某些部分是基于 创建和共享的工作进行的修改,并根据 署名许可中所述的条款使用。

构造函数

AbstractQueuedSynchronizer()

创建初始同步状态为零的新 AbstractQueuedSynchronizer 实例。

AbstractQueuedSynchronizer(IntPtr, JniHandleOwnership)

创建 JNI 对象的托管表示形式时使用的构造函数;由运行时调用。

属性

Class

返回此 Object的运行时类。

(继承自 Object)
ExclusiveOwnerThread

返回上次设置的 setExclusiveOwnerThread线程,如果 null 从未设置,则返回该线程。 - 或 - 设置当前拥有独占访问权限的线程。

(继承自 AbstractOwnableSynchronizer)
ExclusiveQueuedThreads

返回一个集合,该集合包含可能正在等待以独占模式获取的线程。

FirstQueuedThread

如果当前没有线程排队, null 则返回队列中等待时间最长) 线程的第一个 (。

Handle

基础 Android 实例的句柄。

(继承自 Object)
HasContended

查询是否有任何线程曾争用获取此同步器;也就是说,如果某个获取方法曾经被阻止,则为 。

HasQueuedPredecessors

查询是否有任何线程等待获取的时间长于当前线程。

HasQueuedThreads

查询是否有线程正在等待获取。

IsHeldExclusively

true如果与调用) 线程的当前 (保持独占同步,则返回 。

JniIdentityHashCode

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
JniPeerMembers

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

PeerReference

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
QueuedThreads

返回一个集合,其中包含可能正在等待获取的线程。

QueueLength

返回等待获取的线程数的估计值。

SharedQueuedThreads

返回一个集合,该集合包含可能正在等待在共享模式下获取的线程。

State

返回同步状态的当前值。 - 或 - 设置同步状态的值。

ThresholdClass

此 API 支持 Mono for Android 基础结构,不应直接从代码中使用。

ThresholdType

此 API 支持 Mono for Android 基础结构,不应直接从代码中使用。

方法

Acquire(Int32)

在独占模式下获取 ,忽略中断。

AcquireInterruptibly(Int32)

在独占模式下获取,如果中断,则中止。

AcquireShared(Int32)

在共享模式下获取 ,忽略中断。

AcquireSharedInterruptibly(Int32)

在共享模式下获取 ,如果中断,则中止。

Clone()

创建并返回此对象的副本。

(继承自 Object)
CompareAndSetState(Int32, Int32)

如果当前状态值等于预期值,则以原子方式将同步状态设置为给定的更新值。

Dispose()

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
Dispose(Boolean)

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
Equals(Object)

指示某个其他对象是否“等于”此对象。

(继承自 Object)
GetHashCode()

返回对象的哈希代码值。

(继承自 Object)
GetWaitingThreads(AbstractQueuedSynchronizer+ConditionObject)

返回一个集合,其中包含可能正在等待与此同步器关联的给定条件的线程。

GetWaitQueueLength(AbstractQueuedSynchronizer+ConditionObject)

返回与此同步器关联的给定条件上等待的线程数的估计值。

HasWaiters(AbstractQueuedSynchronizer+ConditionObject)

查询是否有线程正在等待与此同步器关联的给定条件。

IsQueued(Thread)

如果给定线程当前已排队,则返回 true。

JavaFinalize()

当垃圾回收确定不再引用对象时,由垃圾回收器对对象调用。

(继承自 Object)
Notify()

唤醒正在等待此对象的监视器的单个线程。

(继承自 Object)
NotifyAll()

唤醒正在等待此对象的监视器的所有线程。

(继承自 Object)
Owns(AbstractQueuedSynchronizer+ConditionObject)

查询给定的 ConditionObject 是否使用此同步器作为其锁。

Release(Int32)

以独占模式发布。

ReleaseShared(Int32)

共享模式下的版本。

SetHandle(IntPtr, JniHandleOwnership)

设置 Handle 属性。

(继承自 Object)
ToArray<T>()

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
ToString()

返回对象的字符串表示形式。

(继承自 Object)
TryAcquire(Int32)

尝试在独占模式下获取。

TryAcquireNanos(Int32, Int64)

尝试在独占模式下获取,如果中断,则中止;如果给定超时时间过,则失败。

TryAcquireShared(Int32)

尝试在共享模式下获取。

TryAcquireSharedNanos(Int32, Int64)

尝试在共享模式下获取,如果中断,则中止;如果给定超时已过,则失败。

TryRelease(Int32)

尝试设置状态以反映独占模式下的发布。

TryReleaseShared(Int32)

尝试设置状态以反映共享模式下的发布。

UnregisterFromRuntime()

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
Wait()

导致当前线程等待,直到它被唤醒,通常是通过 em <通知/em> 或 <em>interrupted</em>。<>

(继承自 Object)
Wait(Int64)

导致当前线程等待,直到它被唤醒,通常是通过 em <通知/em> 或 <em>interrupted</em>,或直到经过一定数量的实时。<>

(继承自 Object)
Wait(Int64, Int32)

导致当前线程等待,直到它被唤醒,通常是通过 em <通知/em> 或 <em>interrupted</em>,或直到经过一定数量的实时。<>

(继承自 Object)

显式接口实现

IJavaPeerable.Disposed()

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
IJavaPeerable.DisposeUnlessReferenced()

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
IJavaPeerable.Finalized()

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
IJavaPeerable.JniManagedPeerState

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
IJavaPeerable.SetJniIdentityHashCode(Int32)

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates)

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)
IJavaPeerable.SetPeerReference(JniObjectReference)

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

(继承自 Object)

扩展方法

JavaCast<TResult>(IJavaObject)

执行 Android 运行时检查的类型转换。

JavaCast<TResult>(IJavaObject)

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

GetJniTypeName(IJavaPeerable)

提供一个框架,用于实现阻塞锁和相关同步器 (信号灯、事件等) ,这些信号灯、事件等依赖于先入先出 (FIFO) 等待队列。

适用于