語言

Phaser 類別

定義

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

[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
繼承
屬性

備註

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

<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)

相當於 #Phaser(Phaser, int) Phaser(parent, 0)

屬性

名稱 Description
ArrivedParties

回傳已抵達該相位槍當前階段的註冊隊伍數量。

Class

傳回這個 Object的運行時間類別。

(繼承來源 Object)
Handle

基礎Android實例的句柄。

(繼承來源 Object)
IsTerminated

如果這把相位槍已經被終止,則會返回 true

JniIdentityHashCode

取得由互通執行時指派給此 Java 對等端的身份雜湊碼。

(繼承來源 Object)
JniManagedPeerState

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
JniPeerMembers

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

Parent

回傳此相位器的父版本, null 若無則回傳。

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)

等待相位器相位從指定相位值或逾時時間過去,等待時中斷則丟 InterruptedException 出;若當前相位不等於指定相位值或該相位器終止,則立即返回。

AwaitAdvanceInterruptibly(Int32)

等待相位器相位從指定相位值前進,等待時中斷則投 InterruptedException 擲;若相位不等於指定相位值或相位槍終止,則立即返回。

BulkRegister(Int32)

會將指定數量的新未抵達隊伍加入此相位槍。

Clone()

建立並傳回這個 對象的複本。

(繼承來源 Object)
Construct(JniObjectReference, JniObjectReferenceOptions)

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
Dispose()

釋放該 Java 節點所持有的資源。

(繼承來源 Object)
Dispose(Boolean)

釋放該 Java 節點所持有的資源。

(繼承來源 Object)
DisposeUnlessReferenced()

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
Equals(Object)

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
Equals(Object)

指出其他物件是否「等於」這個物件。

(繼承來源 Object)
ForceTermination()

強制此相位槍進入終端狀態。

GetHashCode()

傳回此物件的雜湊碼值。

(繼承來源 Object)
JavaFinalize()
已淘汰.

當垃圾收集決定不再參考物件時,垃圾收集行程在 物件上呼叫。

(繼承來源 Object)
Notify()

喚醒正在等候此物件監視器的單一線程。

(繼承來源 Object)
NotifyAll()

喚醒正在等候此物件監視器的所有線程。

(繼承來源 Object)
OnAdvance(Int32, Int32)

可覆寫的方法,用於在即將相位前進時執行動作,並控制終止。

Register()

這把相位槍會新增一個未抵達的隊伍。

SetHandle(IntPtr, JniHandleOwnership)

設定 Handle 屬性。

(繼承來源 Object)
SetPeerReference(JniObjectReference, JniObjectReferenceOptions)

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
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()

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
IJavaPeerable.Finalized()

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
IJavaPeerable.JniObjectReferenceControlBlock

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
IJavaPeerable.SetJniIdentityHashCode(Int32)

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates)

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)
IJavaPeerable.SetPeerReference(JniObjectReference)

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

(繼承來源 JavaObject)

擴充方法

名稱 Description
GetJniTypeName(IJavaPeerable)

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

JavaAs<TResult>(IJavaPeerable)

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

JavaCast<TResult>(IJavaObject)

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

JavaCast<TResult>(IJavaObject)

一個可重複使用的同步障礙,功能類似 CyclicBarrierCountDownLatch 支援更靈活的使用。

TryJavaCast<TResult>(IJavaPeerable, TResult)

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

適用於