Phaser 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
一個可重複使用的同步障礙,功能類似 CyclicBarrier 且 CountDownLatch 支援更靈活的使用。
[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
- 繼承
- 屬性
備註
一個可重複使用的同步障礙,功能類似 CyclicBarrier 且 CountDownLatch 支援更靈活的使用。
<b>登記。</b> 與其他障礙不同,相位器上登記/同步的人數<><>可能會隨時間變化。 任務可隨時註冊(使用方法 #register、 #bulkRegister,或建立初始數量的建構器),並可選擇在任何抵達時取消註冊(使用 #arriveAndDeregister)。 如同大多數基本同步結構,註冊與取消登記僅影響內部計數;它們不會建立任何進一步的內部帳目管理,因此任務無法查詢是否已註冊。 (不過,你也可以透過子類別這個類別來引入這種帳務。)
<b>同步。</b> 如 CyclicBarriera , a Phaser 可能反覆等待。 方法 #arriveAndAwaitAdvance 的效果類似 java.util.concurrent.CyclicBarrier#await CyclicBarrier.await於。 每一代相位器都有相應的相位號。 相位數從零開始,當所有隊伍抵達相位槍時推進,抵達 Integer.MAX_VALUE後繞圈至零。 使用相位號碼使得在抵達相位器時及等待其他相位器時,能透過兩種方式獨立控制行動,任何註冊方皆可啟動:
<UL>
<李><乙>:抵達。</b> 方法 #arrive 與 #arriveAndDeregister 記錄到達。 這些方法不會阻擋,而是回傳一個相關的 <電磁>波到達相位數</em>;也就是該到達所作用的相位數。 當某階段的最後一隊隊伍抵達時,會執行一個可選行動,該階段會推進。 這些動作由當事人觸發相位提前執行,並依覆寫方法排列,該方法 #onAdvance(int, int)同時控制終止。 覆寫此方法類似於,但比提供一個障礙作用更 CyclicBarrier為靈活。
<李><乙>等待。</b> 方法需要一個參數來表示抵達相位數,當相位器前進到(或已經處於)不同相位時,該參數 #awaitAdvance 會返回。 與類似的結構 CyclicBarrier不同, awaitAdvance 方法即使等待執行緒被中斷,仍持續等待。 也有可中斷與逾時版本,但在任務可中斷等待或逾時時遇到的例外,並不改變相位器的狀態。 必要時,您可以在這些例外的處理程序內執行相關恢復,通常在呼叫 forceTermination後。 相位槍也可用於執行任務 ForkJoinPool的 。 若池的平行程度能容納最多同時被封鎖的隊伍,則可確保進展。
</ul>
<b>解僱。</b> 相位器可能會進入 <電磁>終端</電磁> 狀態,可用方法 #isTerminated檢查。 終止時,所有同步方法立即返回,無需等待提前,並以負回傳值表示。 同樣地,解僱時嘗試登記也無效。 當呼叫 onAdvance 返回 true時,終止即被觸發。 若註銷導致註冊當事人數量降至零,預設實作會回傳 true 。 如下所示,當相位器以固定次數的迭代控制動作時,通常可以直接覆寫此方法,當當前相位數達到某個閾值時終止。 也有方法 #forceTermination 可以突然釋放等待執行緒並讓它們終止。
<b>分級。</b> 相位槍可採用 <em>tiered</em> (即以樹狀結構建造)以減少爭用。 若有大量隊伍參與,否則會產生高昂的同步爭用成本,則可改為讓多個子相位槍群組共用一個父裝置。 即使每操作額外負擔增加,這仍能大幅提升吞吐量。
在分層相位器的樹狀結構中,子相位器與父相位器的註冊與註銷會自動管理。 當子相位器的註冊方數非零(如建構子所定 #Phaser(Phaser,int) , #register或 #bulkRegister時),子相位器即與其父相位器註冊。 當因呼叫 而 #arriveAndDeregister註冊當事方數變為零時,子相位器即從其父相位器中註銷。
<b>監控。</b> 雖然同步方法僅可由註冊方調用,但任何呼叫者都可以監控相位器的當前狀態。 在任何時刻,總共有多個 #getRegisteredParties 政黨,其中各方 #getArrivedParties 已抵達當前階段(#getPhase)。 當剩餘的(#getUnarrivedParties)隊伍抵達時,階段會推進。 這些方法回傳的值可能反映瞬態狀態,因此通常對同步控制並不有用。 方法 #toString 會以方便非正式監控的形式回傳這些狀態查詢的快照。
記憶一致性效應:在任何形式的到達方法 <i>之前的動作——<>在對應的階段提前之前發生;onAdvance 動作(若存在),而這些動作又發生在相位前進後的行動之前。
<b>範例使用例:</b>
Phaser A可用來代替aCountDownLatch來控制一個服務可變數量隊伍的單次行動。 典型的慣用語是,該方法先設定為暫存器,然後啟動所有動作,最後取消註冊,如下:
{@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 任務,你可以使用以下形式的程式碼,假設一個任務類別在建構時會註冊 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 值主要取決於預期的同步速率。 對於極小的每相任務體(因此速率高)可能適合低至四的數值,對於極大的任務體則可達數百個。
<b>實施說明:</b> 此實作限制最大締約方數為65535人。 嘗試登記更多當事人會導致 IllegalStateException。 不過,你可以且應該設計分層相位槍,以容納任意龐大的參與者群。
在 1.7 版本中加入。
Java 文件 java.util.concurrent.Phaser。
本頁部分內容為基於 Open Source Project 所創建與分享的作品,並依授權條款所描述的使用進行修改。
建構函式
| 名稱 | Description |
|---|---|
| Phaser() |
建立一個新的相位器,沒有初始註冊的隊伍、沒有父體,初始相位編號為0。 |
| Phaser(Int32) |
建立一個新的相位器,包含指定數量的未抵達者,無父方,初始相位編號為0。 |
| Phaser(IntPtr, JniHandleOwnership) |
建立 JNI 物件的 Managed 表示法時使用的建構函式;由運行時間呼叫。 |
| Phaser(Phaser, Int32) |
建立一台新的相位器,包含指定的父艦及註冊未抵達的隊伍數量。 |
| Phaser(Phaser) |
相當於 |
屬性
| 名稱 | Description |
|---|---|
| ArrivedParties |
回傳已抵達該相位槍當前階段的註冊隊伍數量。 |
| Class |
傳回這個 |
| Handle |
基礎Android實例的句柄。 (繼承來源 Object) |
| IsTerminated |
如果這把相位槍已經被終止,則會返回 |
| JniIdentityHashCode |
取得由互通執行時指派給此 Java 對等端的身份雜湊碼。 (繼承來源 Object) |
| JniManagedPeerState |
一個可重複使用的同步障礙,功能類似 |
| JniPeerMembers |
一個可重複使用的同步障礙,功能類似 |
| Parent |
回傳此相位器的父版本, |
| PeerReference |
取得這個 Java 節點的 JNI 物件參考。 (繼承來源 Object) |
| Phase |
回傳當前相位號。 |
| RegisteredParties |
回傳此相位器註冊的政黨數量。 |
| Root |
回傳此相位器的根祖先,若沒有父相位,則與此相位相同。 |
| ThresholdClass |
此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。 |
| ThresholdType |
此 API 支援 Mono for Android 基礎架構,並非直接從你的程式碼中使用。 |
| UnarrivedParties |
回傳尚未抵達本階段相位槍的註冊隊伍數量。 |
方法
| 名稱 | Description |
|---|---|
| Arrive() |
他直接拿到這把相位槍,沒等其他人到。 |
| ArriveAndAwaitAdvance() |
抵達這把相位槍,等待其他人。 |
| ArriveAndDeregister() |
抵達這把相位槍後,無需等待其他人到齊就自動取消註冊。 |
| AwaitAdvance(Int32) |
等待相位器相位從給定相位值前進,若當前相位不等於相位值或相位器終止,則立即返回。 |
| AwaitAdvanceInterruptibly(Int32, Int64, TimeUnit) |
等待相位器相位從指定相位值或逾時時間過去,等待時中斷則丟 |
| AwaitAdvanceInterruptibly(Int32) |
等待相位器相位從指定相位值前進,等待時中斷則投 |
| BulkRegister(Int32) |
會將指定數量的新未抵達隊伍加入此相位槍。 |
| Clone() |
建立並傳回這個 對象的複本。 (繼承來源 Object) |
| Construct(JniObjectReference, JniObjectReferenceOptions) |
一個可重複使用的同步障礙,功能類似 |
| Dispose() |
釋放該 Java 節點所持有的資源。 (繼承來源 Object) |
| Dispose(Boolean) |
釋放該 Java 節點所持有的資源。 (繼承來源 Object) |
| DisposeUnlessReferenced() |
一個可重複使用的同步障礙,功能類似 |
| Equals(Object) |
一個可重複使用的同步障礙,功能類似 |
| Equals(Object) |
指出其他物件是否「等於」這個物件。 (繼承來源 Object) |
| ForceTermination() |
強制此相位槍進入終端狀態。 |
| GetHashCode() |
傳回此物件的雜湊碼值。 (繼承來源 Object) |
| JavaFinalize() |
已淘汰.
當垃圾收集決定不再參考物件時,垃圾收集行程在 物件上呼叫。 (繼承來源 Object) |
| Notify() |
喚醒正在等候此物件監視器的單一線程。 (繼承來源 Object) |
| NotifyAll() |
喚醒正在等候此物件監視器的所有線程。 (繼承來源 Object) |
| OnAdvance(Int32, Int32) |
可覆寫的方法,用於在即將相位前進時執行動作,並控制終止。 |
| Register() |
這把相位槍會新增一個未抵達的隊伍。 |
| SetHandle(IntPtr, JniHandleOwnership) |
設定 Handle 屬性。 (繼承來源 Object) |
| SetPeerReference(JniObjectReference, JniObjectReferenceOptions) |
一個可重複使用的同步障礙,功能類似 |
| ToArray<T>() |
從這個 Java 陣列包裝器建立一個受管理陣列。 (繼承來源 Object) |
| ToString() |
傳回物件的字串表示。 (繼承來源 Object) |
| UnregisterFromRuntime() |
將此 Java 節點從互通執行時中取消註冊。 (繼承來源 Object) |
| Wait() |
讓目前線程等候直到喚醒為止,通常是藉由em <notified/em>或<em>interrupted</em> 來喚醒它。<> (繼承來源 Object) |
| Wait(Int64, Int32) |
讓目前的線程等到喚醒為止,通常是因為 <em>notified</em> 或 <em>interrupted</em>,或直到經過一定數量的實時為止。 (繼承來源 Object) |
| Wait(Int64) |
讓目前的線程等到喚醒為止,通常是因為 <em>notified</em> 或 <em>interrupted</em>,或直到經過一定數量的實時為止。 (繼承來源 Object) |
明確介面實作
| 名稱 | Description |
|---|---|
| IJavaPeerable.Disposed() |
一個可重複使用的同步障礙,功能類似 |
| IJavaPeerable.Finalized() |
一個可重複使用的同步障礙,功能類似 |
| IJavaPeerable.JniObjectReferenceControlBlock |
一個可重複使用的同步障礙,功能類似 |
| IJavaPeerable.SetJniIdentityHashCode(Int32) |
一個可重複使用的同步障礙,功能類似 |
| IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates) |
一個可重複使用的同步障礙,功能類似 |
| IJavaPeerable.SetPeerReference(JniObjectReference) |
一個可重複使用的同步障礙,功能類似 |
擴充方法
| 名稱 | Description |
|---|---|
| GetJniTypeName(IJavaPeerable) |
取得實例 |
| JavaAs<TResult>(IJavaPeerable) |
試著強制 |
| JavaCast<TResult>(IJavaObject) |
執行 Android 執行時間檢查的類型轉換。 |
| JavaCast<TResult>(IJavaObject) |
一個可重複使用的同步障礙,功能類似 |
| TryJavaCast<TResult>(IJavaPeerable, TResult) |
試著強制 |