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 值來表示狀態的同步器類型的有用基礎。 子類別必須定義改變此狀態的受保護方法,並定義該狀態在物件被取得或釋放時的意義。 基於這些,該類別的其他方法執行所有排隊與阻擋機制。 子類別可以維護其他狀態欄位,但只能維持使用方法 #setState#getState操作的原子更新int值,並且#compareAndSetState會根據同步進行追蹤。

子類別應定義為非公開的內部輔助類別,用於實作其包圍類別的同步屬性。 類別 AbstractQueuedSynchronizer 不實作任何同步介面。 它定義 #acquireInterruptibly 了像是 concrete lock 及相關同步器可根據適當調用來實作其公開方法的方法。

此類別支援預設 <的 em>專屬</em> 模式與 <em>共享</em> 模式之一或兩者。 當以獨佔模式取得時,其他執行緒嘗試取得無法成功。 多執行緒取得的共享模式可能(但不一定)成功。 這個職業沒有 &明白!這些差異除了在機械層面外,當共享模式獲得成功時,下一個等待執行緒(如果存在)也必須判斷是否能獲得。 不同模式等待的執行緒共用同一個 FIFO 隊列。 通常,實作子類別只支援其中一種模式,但兩者都可能同時出現,例如在 ReadWriteLock。 僅支援異他或僅共享模式的子類別,不必定義支援未使用模式的方法。

此類別定義了一個巢狀ConditionObject類別,可作為Condition支援獨佔模式的子類別實作,該方法#isHeldExclusively報告同步是否僅針對當前執行緒進行,呼叫該#getState#release的方法會完全釋放此物件,且#acquire根據儲存的狀態值,最終將該物件恢復至先前取得的狀態。 否則沒有 AbstractQueuedSynchronizer 方法會產生此類條件,若無法滿足此限制,則不應使用。 的 ConditionObject 行為當然取決於其同步器實作的語意。

此類別提供內部佇列的檢查、儀器與監控方法,以及條件物件類似的方法。 這些可以依需求匯出到使用同步 AbstractQueuedSynchronizer 機制的類別。

此類別的序列化僅儲存底層的原子整數維持狀態,因此反序列化的物件執行緒佇列為空。 典型需要序列化的子類別會定義一個 readObject 方法,在反序列化時將此狀態恢復到已知初始狀態。

<h2>使用率/<h2>

若要使用此類別作為同步器的基礎,請根據適用方式重新定義以下方法,透過檢查和/或修改同步狀態,使用 #getState#setState 且/或 #compareAndSetState

<烏爾><李#tryAcquire<>李#tryRelease<>李<#tryAcquireShared>李<>#tryReleaseShared李>#isHeldExclusively</烏爾>

這些方法預設都會拋 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>;

(共享模式類似,但可能涉及串聯訊號。)

由於 acquire 的檢查是在排隊前被觸發,新取得的執行緒可能會<>先行衝刺<或超越>其他被封鎖並排隊的執行緒。 不過,若有需要,你可以透過內部調用一種或多種檢查方法來定義 tryAcquire 和/或 tryAcquireShared 停用駁船,從而提供 <em>fair</em> FIFO 的取得命令。 特別地,大多數公平同步器可以定義 tryAcquire 回傳 false ,當( #hasQueuedPredecessors 此方法專為公平同步器設計)回傳 true時。 還有其他變化。

預設的駁船策略(也稱為 <em>greedy</em>、 <em>放棄</em>,以及 <em>車隊避開</em>)策略的吞吐量與可擴展性通常最高。 雖然這不保證公平或無飢餓,但較早排隊的執行緒允許在後排執行緒之前重新爭奪,且每次重新爭論都有公平機率勝過新進執行緒。 此外,雖然獲得並未Spin”通常而言,它們可能會在阻塞前,穿插其他計算進行多次呼叫 tryAcquire 。 這在排他同步僅短暫維持時,提供了大部分旋轉的好處,而非同步時則承擔大部分風險。 若有需要,你可以在呼叫前加以取得方法,並進行「快速路徑」檢查,或#hasContended#hasQueuedThreads僅在同步器可能不會被爭用時才進行。

此類別提供高效且可擴展的同步基礎,部分原因是其應用範圍專門用於能依賴 int 狀態、獲取與釋放參數,以及內部 FIFO 等待佇列的同步器。 當這還不夠時,你可以從較低層 java.util.concurrent.atomic atomic 級開始用類別、自訂 java.util.Queue 類別和 LockSupport 阻擋支援來建立同步器。

<h2>使用範例</h2>

這裡有一個非重入互斥鎖類別,使用值 0 表示解鎖狀態,1 表示鎖定狀態。 雖然非重入鎖不一定要求記錄當前擁有者執行緒,但此類別仍會記錄,以便監控使用情況。 它也支援條件並公開一些儀器化方法:

{@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 文件 java.util.concurrent.locks.AbstractQueuedSynchronizer

本頁部分內容為基於 Open Source Project 所創建與分享的作品,並依授權條款所描述的使用進行修改。

建構函式

名稱 Description
AbstractQueuedSynchronizer()

建立 AbstractQueuedSynchronizer 一個初始同步狀態為零的新實例。

AbstractQueuedSynchronizer(IntPtr, JniHandleOwnership)

用於建立 JNI 物件受管理表示的建構器;由執行時呼叫。

屬性

名稱 Description
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 基礎架構,並非直接從你的程式碼中使用。

方法

名稱 Description
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)

查詢給定的條件物件是否使用此同步器作為鎖。

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>中斷</em> 來喚醒。

(繼承來源 Object)
Wait(Int64, Int32)

會讓目前執行緒等待喚醒,通常是透過 <em>通知</><em 或 em>中斷</em>,或是經過一定的真實時間。

(繼承來源 Object)
Wait(Int64)

會讓目前執行緒等待喚醒,通常是透過 <em>通知</><em 或 em>中斷</em>,或是經過一定的真實時間。

(繼承來源 Object)

明確介面實作

名稱 Description
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)

擴充方法

名稱 Description
GetJniTypeName(IJavaPeerable)

取得實例 self類型的 JNI 名稱。

JavaAs<TResult>(IJavaPeerable)

試著強制self輸入 TResult,檢查 強制在 Java 端是否有效。

JavaCast<TResult>(IJavaObject)

執行 Android 執行時間檢查的類型轉換。

JavaCast<TResult>(IJavaObject)

提供一個框架,用於實作依賴先入先出(FIFO)等待佇列的阻塞鎖及相關同步器(信號量、事件等)。

TryJavaCast<TResult>(IJavaPeerable, TResult)

試著強制self輸入 TResult,檢查 強制在 Java 端是否有效。

適用於