AbstractQueuedSynchronizer 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
提供一個框架,用於實作依賴先入先出(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
- 繼承
- 屬性
- 實作
備註
提供一個框架,用於實作依賴先入先出(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(IntPtr, JniHandleOwnership) |
用於建立 JNI 物件受管理表示的建構器;由執行時呼叫。 |
屬性
| 名稱 | Description |
|---|---|
| Class |
回傳此 |
| ExclusiveOwnerThread |
回傳最後一次設定在 的 |
| ExclusiveQueuedThreads |
回傳包含可能在獨佔模式下等待獲取的執行緒的集合。 |
| FirstQueuedThread |
回傳佇列中第一個(等待時間最長的)執行緒,或 |
| Handle |
底層 Android 實例的帳號。 (繼承來源 Object) |
| HasContended |
查詢是否有執行緒曾經爭奪過此同步器;也就是說,如果某個獲取方法曾經被阻擋過。 |
| HasQueuedPredecessors |
查詢是否有執行緒比目前執行緒等待獲得的時間更久。 |
| HasQueuedThreads |
查詢是否有執行緒正在等待接收。 |
| IsHeldExclusively |
若同步僅針對當前(呼叫)執行緒進行,則回傳 |
| 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) |
取得實例 |
| JavaAs<TResult>(IJavaPeerable) |
試著強制 |
| JavaCast<TResult>(IJavaObject) |
執行 Android 執行時間檢查的類型轉換。 |
| JavaCast<TResult>(IJavaObject) |
提供一個框架,用於實作依賴先入先出(FIFO)等待佇列的阻塞鎖及相關同步器(信號量、事件等)。 |
| TryJavaCast<TResult>(IJavaPeerable, TResult) |
試著強制 |