Phaser 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
可重複使用的同步處理屏障,類似於 和 CountDownLatch
的功能CyclicBarrier
,但支援更有彈性的使用方式。
[Android.Runtime.Register("java/util/concurrent/Phaser", DoNotGenerateAcw=true)]
public class Phaser : Java.Lang.Object
[<Android.Runtime.Register("java/util/concurrent/Phaser", DoNotGenerateAcw=true)>]
type Phaser = class
inherit Object
- 繼承
- 屬性
備註
可重複使用的同步處理屏障,類似於 和 CountDownLatch
的功能CyclicBarrier
,但支援更有彈性的使用方式。
<b>註冊。</b> 不同於其他障礙的情況,在階段器上同步處理之已登錄</em> 的合作物件<>數目可能會隨著時間而有所不同。 工作可以隨時註冊(使用方法 #register
、 #bulkRegister
或建立初始合作對象數目的建構函式形式),並選擇性地在任何抵達時取消註冊(使用 #arriveAndDeregister
)。 與最基本的同步處理建構一樣,註冊和取消註冊只會影響內部計數:它們不會建立任何進一步的內部記帳,因此工作無法查詢其是否已註冊。 (不過,您可以透過分類別化這個類別來介紹這類記帳。
<b>同步處理。</b> 如同 CyclicBarrier
, Phaser
可能會重複等候 。 方法 #arriveAndAwaitAdvance
的效果類似於 java.util.concurrent.CyclicBarrier#await CyclicBarrier.await
。 階段器的每個世代都有相關聯的階段編號。 階段編號從零開始,當各方到達階段器時,會往前推進,在到達 Integer.MAX_VALUE
之後繞到零。 使用階段編號可透過任何已註冊的一方可叫用的兩種方法,在抵達階段器及等候其他人時獨立控制動作:
<ul>
<李><b>抵達。</b> 方法和#arrive
#arriveAndDeregister
記錄抵達。 這些方法不會封鎖,但會傳回相關聯的 <em>抵達階段號碼</em>;也就是套用抵達的階段器階段編號。 當指定階段的最後一方到達時,會執行選擇性的動作,階段會往前推進。 這些動作是由觸發階段前進的一方所執行,並透過覆寫 方法 #onAdvance(int, int)
來排列,同時控制終止。 覆寫此方法與 類似,但比 提供屏障動作給 CyclicBarrier
更有彈性。
<李><b>等待。</b> 方法 #awaitAdvance
需要指出抵達階段號碼的自變數,並在階段器前進到 (或 已在) 不同的階段時傳回 。 不同於使用 CyclicBarrier
的類似建構,方法 awaitAdvance
會繼續等候,即使等候線程中斷也一樣。 中斷和逾時版本也可供使用,但工作中斷或逾時時所遇到的例外狀況不會變更階段器的狀態。 如有必要,您可以在這些例外狀況的處理程式內執行任何相關聯的復原,通常叫 forceTermination
用 之後。 在中 ForkJoinPool
執行的工作也可以使用分階段器。 如果集區的平行處理原則層級可以容納同時封鎖的合作物件數目上限,就會確保進度。
</ul>
<b>終止。</b> 階段器可能會進入 <em>終止</em> 狀態,可能使用 方法 #isTerminated
來檢查。 終止時,所有同步處理方法都會立即傳回,而不需要等候進階,如負傳回值所表示。 同樣地,在終止時嘗試註冊沒有任何作用。 當的調用 onAdvance
傳回 true
時,就會觸發終止。 如果取消註冊導致已註冊的合作物件數目變成零,則預設實作會傳回 true
。 如下所述,當分階段器控制具有固定反覆項目數目的動作時,覆寫此方法通常很方便,以在目前的階段編號達到臨界值時造成終止。 方法 #forceTermination
也可用來突然釋放等候的線程,並允許它們終止。
<b>階層處理。</b> 分階段器可能是 <em>階層式</em> (亦即在樹狀結構中建構)以減少爭用。 具有大量合作物件的分階段器可能會改為設定大量同步處理競爭成本,讓子階段器群組共用一個通用父系。 即使每個作業的額外負荷增加,這也可能會大幅增加輸送量。
在階層式分階段器樹狀結構中,會自動管理子階段器及其父系的註冊和取消註冊。 每當子階段器註冊的合作對象數目變成非零時(如建構#register
函式、 或 #bulkRegister
中#Phaser(Phaser,int)
建立),子階段器就會向其父代註冊。 每當註冊的合作對象數目因為叫用 #arriveAndDeregister
而變成零時,子階段器就會從其父代取消註冊。
<b>監視。</b> 雖然同步處理方法只能由已註冊的各方叫用,但任何呼叫端都可以監視階段器的目前狀態。 在任何指定的時刻, #getRegisteredParties
共有各方,其中 #getArrivedParties
已經到達目前的階段(#getPhase
)。 當其餘的(#getUnarrivedParties
)各方到達時,階段會提前。 這些方法傳回的值可能會反映暫時性狀態,因此不適用於同步處理控制。 方法 #toString
會以方便非正式監視的形式傳回這些狀態查詢的快照集。
記憶體一致性效果:在任何形式的抵達方法<之前執行的動作,i 發生在之前></i> 對應的階段前和 onAdvance 動作(如果有),接著會在階段前進之後發生之前執行的動作。
<b>範例使用方式:</b>
Phaser
可以使用 ,而不是 CountDownLatch
用來控制一次性動作,以處理可變數目的政黨。 典型的成語是將此方法設定為先註冊,然後啟動所有動作,然後取消註冊,如下所示:
{@code
void runTasks(List<Runnable> tasks) {
Phaser startingGate = new Phaser(1); // "1" to register self
// create and start threads
for (Runnable task : tasks) {
startingGate.register();
new Thread(() -> {
startingGate.arriveAndAwaitAdvance();
task.run();
}).start();
}
// deregister self to allow threads to proceed
startingGate.arriveAndDeregister();
}}
導致一組線程重複執行指定次數反覆執行的動作的其中一種方法是覆寫 onAdvance
:
{@code
void startTasks(List<Runnable> tasks, int iterations) {
Phaser phaser = new Phaser() {
protected boolean onAdvance(int phase, int registeredParties) {
return phase >= iterations - 1 || registeredParties == 0;
}
};
phaser.register();
for (Runnable task : tasks) {
phaser.register();
new Thread(() -> {
do {
task.run();
phaser.arriveAndAwaitAdvance();
} while (!phaser.isTerminated());
}).start();
}
// allow threads to proceed; don't wait for them
phaser.arriveAndDeregister();
}}
如果主要工作稍後必須等候終止,它可能會重新註冊,然後執行類似的迴圈:
{@code
// ...
phaser.register();
while (!phaser.isTerminated())
phaser.arriveAndAwaitAdvance();}
相關建構可用來等候特定階段編號的內容,在此內容中,您確定階段永遠不會包裝。Integer.MAX_VALUE
例如:
{@code
void awaitPhase(Phaser phaser, int phase) {
int p = phaser.register(); // assumes caller not already registered
while (p < phase) {
if (phaser.isTerminated())
// ... deal with unexpected termination
else
p = phaser.arriveAndAwaitAdvance();
}
phaser.arriveAndDeregister();
}}
若要使用分階段器樹狀結構建立一組 n
工作,您可以使用下列表單的程式代碼,假設 Task 類別具有接受建構時所註冊 Phaser
的 建構函式。 叫用 build(new Task[n], 0, n, new Phaser())
之後,就可以啟動這些工作,例如,提交至集區:
{@code
void build(Task[] tasks, int lo, int hi, Phaser ph) {
if (hi - lo > TASKS_PER_PHASER) {
for (int i = lo; i < hi; i += TASKS_PER_PHASER) {
int j = Math.min(i + TASKS_PER_PHASER, hi);
build(tasks, i, j, new Phaser(ph));
}
} else {
for (int i = lo; i < hi; ++i)
tasks[i] = new Task(ph);
// assumes new Task(ph) performs ph.register()
}
}}
的最佳值 TASKS_PER_PHASER
主要取決於預期的同步處理速率。 最小值為 4 的值可能適用於極小的個別階段任務主體(因此高比率),或高達數百個用於極大型工作機構。
<b>實作注意事項:</b> 此實作會將合作物件數目上限限制為 65535。 嘗試註冊其他合作物件會導致 IllegalStateException
。 不過,您可以和應該建立階層式分階段器,以容納任意大型參與者集。
已在1.7中新增。
的 java.util.concurrent.Phaser
Java 檔。
此頁面的部分是根據 Android 開放原始碼專案所建立和共用的工作進行修改,並根據 Creative Commons 2.5 屬性授權中所述的詞彙使用。
建構函式
Phaser() |
建立沒有初始註冊合作對象、沒有父代和初始階段編號0的新階段器。 |
Phaser(Int32) |
建立具有指定數目的已註冊未加入合作對象、沒有父系和初始階段編號 0 的新階段器。 |
Phaser(IntPtr, JniHandleOwnership) |
建立 JNI 物件的 Managed 表示法時使用的建構函式;由運行時間呼叫。 |
Phaser(Phaser) |
相當於 |
Phaser(Phaser, Int32) |
使用指定的父代和已註冊的未婚合作對象數目,建立新的階段器。 |
屬性
ArrivedParties |
傳回已抵達這個階段器目前階段的已註冊合作對象數目。 |
Class |
傳回這個 |
Handle |
基礎Android實例的句柄。 (繼承來源 Object) |
IsTerminated |
如果已經終止此階段器,則傳 |
JniIdentityHashCode |
可重複使用的同步處理屏障,類似於 和 |
JniPeerMembers |
可重複使用的同步處理屏障,類似於 和 |
Parent |
傳回這個階段器的父代,如果沒有 |
PeerReference |
可重複使用的同步處理屏障,類似於 和 |
Phase |
傳回目前的階段編號。 |
RegisteredParties |
傳回在這個階段器中註冊的合作物件數目。 |
Root |
傳回這個階段器的根祖系,如果這個階段器沒有父代,則與這個階段器相同。 |
ThresholdClass |
此 API 支援適用於 Android 的 Mono 基礎結構,並不適合直接從您的程式代碼使用。 |
ThresholdType |
此 API 支援適用於 Android 的 Mono 基礎結構,並不適合直接從您的程式代碼使用。 |
UnarrivedParties |
傳回尚未到達此階段之目前階段的已註冊合作對象數目。 |
方法
Arrive() |
到達這個階段器,而不等待其他人到達。 |
ArriveAndAwaitAdvance() |
到達這個階段器,並等候其他人。 |
ArriveAndDeregister() |
到達這個階段器並取消註冊,而不等待其他人到達。 |
AwaitAdvance(Int32) |
等候這個階段的階段,從指定的階段值前進,如果目前的階段不等於指定的階段值,或終止這個階段器,則立即傳回。 |
AwaitAdvanceInterruptibly(Int32) |
等候這個階段的階段,從指定的階段值往前推進、在等候時中斷時擲 |
AwaitAdvanceInterruptibly(Int32, Int64, TimeUnit) |
等候這個階段的階段,從指定的階段值或經過的指定逾時前進,在等候時中斷時擲 |
BulkRegister(Int32) |
將指定的未加入合作物件數目新增至這個階段器。 |
Clone() |
建立並傳回這個 對象的複本。 (繼承來源 Object) |
Dispose() |
可重複使用的同步處理屏障,類似於 和 |
Dispose(Boolean) |
可重複使用的同步處理屏障,類似於 和 |
Equals(Object) |
指出其他物件是否「等於」這個物件。 (繼承來源 Object) |
ForceTermination() |
強制此階段器進入終止狀態。 |
GetHashCode() |
傳回此物件的雜湊碼值。 (繼承來源 Object) |
JavaFinalize() |
當垃圾收集決定不再參考物件時,垃圾收集行程在 物件上呼叫。 (繼承來源 Object) |
Notify() |
喚醒正在等候此物件監視器的單一線程。 (繼承來源 Object) |
NotifyAll() |
喚醒正在等候此物件監視器的所有線程。 (繼承來源 Object) |
OnAdvance(Int32, Int32) |
可覆寫的方法,在即將進行階段前執行動作,以及控制終止。 |
Register() |
將新的未加入合作物件新增至這個階段器。 |
SetHandle(IntPtr, JniHandleOwnership) |
設定 Handle 屬性。 (繼承來源 Object) |
ToArray<T>() |
可重複使用的同步處理屏障,類似於 和 |
ToString() |
傳回物件的字串表示。 (繼承來源 Object) |
UnregisterFromRuntime() |
可重複使用的同步處理屏障,類似於 和 |
Wait() |
讓目前線程等候直到喚醒為止,通常是藉由em <notified/em>或<em>interrupted</em> 來喚醒它。<> (繼承來源 Object) |
Wait(Int64) |
讓目前的線程等到喚醒為止,通常是因為 <em>notified</em> 或 <em>interrupted</em>,或直到經過一定數量的實時為止。 (繼承來源 Object) |
Wait(Int64, Int32) |
讓目前的線程等到喚醒為止,通常是因為 <em>notified</em> 或 <em>interrupted</em>,或直到經過一定數量的實時為止。 (繼承來源 Object) |
明確介面實作
IJavaPeerable.Disposed() |
可重複使用的同步處理屏障,類似於 和 |
IJavaPeerable.DisposeUnlessReferenced() |
可重複使用的同步處理屏障,類似於 和 |
IJavaPeerable.Finalized() |
可重複使用的同步處理屏障,類似於 和 |
IJavaPeerable.JniManagedPeerState |
可重複使用的同步處理屏障,類似於 和 |
IJavaPeerable.SetJniIdentityHashCode(Int32) |
可重複使用的同步處理屏障,類似於 和 |
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
可重複使用的同步處理屏障,類似於 和 |
IJavaPeerable.SetPeerReference(JniObjectReference) |
可重複使用的同步處理屏障,類似於 和 |
擴充方法
JavaCast<TResult>(IJavaObject) |
執行 Android 執行時間檢查的類型轉換。 |
JavaCast<TResult>(IJavaObject) |
可重複使用的同步處理屏障,類似於 和 |
GetJniTypeName(IJavaPeerable) |
可重複使用的同步處理屏障,類似於 和 |