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> 他のバリアの場合とは異なり、フェイザーで同期する登録/em> のパーティ<><の数は、時間の経過と伴って異なる場合があります。 タスクはいつでも登録できます (メソッド #register
、 #bulkRegister
またはパーティの初期数を確立するコンストラクターの形式を使用)。また、必要に応じて、任意の到着時に登録を解除できます (使用 #arriveAndDeregister
)。 ほとんどの基本的な同期コンストラクトの場合と同様に、登録と登録解除は内部カウントにのみ影響します。それ以上の内部ブックキーピングは確立されないため、タスクは登録されているかどうかを照会できません。 (ただし、このクラスをサブクラス化することで、このようなブックキーピングを導入できます。
<b>同期。</b> a CyclicBarrier
のように、a Phaser
を繰り返し待機できます。 メソッド #arriveAndAwaitAdvance
の効果は次に似ています java.util.concurrent.CyclicBarrier#await CyclicBarrier.await
。 フェイザーの各生成には、関連するフェーズ番号があります。 フェーズ番号はゼロから始まり、すべての当事者がフェイザーに到着すると進み、到達後にゼロに折り返されます Integer.MAX_VALUE
。 フェーズ番号を使用すると、任意の登録済みパーティによって呼び出される可能性のある 2 種類のメソッドを使用して、フェイザーに到着した場合と他のユーザーを待機するときのアクションを独立して制御できます。
<ul>
<li><b>Arrival.</b> メソッド #arrive
と #arriveAndDeregister
レコード到着。 これらのメソッドはブロックしませんが、関連付けられた <em>到着フェーズ番号</em>、つまり到着が適用されたフェイザーのフェーズ番号を返します。 特定のフェーズの最終パーティが到着すると、オプションのアクションが実行され、フェーズが進みます。 これらのアクションは、フェーズの進行をトリガーするパーティによって実行され、終了を制御するメソッド #onAdvance(int, int)
をオーバーライドすることによって配置されます。 このメソッドのオーバーライドは、バリア アクション CyclicBarrier
を提供するよりも柔軟性に似ていますが、.
<li><b>Waiting.</b> メソッド #awaitAdvance
には、到着フェーズ番号を示す引数が必要であり、フェイザーが別のフェーズに進む (または既にある) ときに戻ります。 使用 CyclicBarrier
する同様の構造とは異なり、待機中のスレッドが中断された場合でも、メソッド awaitAdvance
は待機を続けます。 割り込み可能なバージョンとタイムアウト バージョンも使用できますが、タスクが中断的に待機中またはタイムアウト時に発生した例外は、フェイザーの状態を変更しません。 必要に応じて、多くの場合、呼び出した後に、これらの例外のハンドラー内で関連する任意の回復を forceTermination
実行できます。 フェイザーは、 ForkJoinPool
. プールの並列処理レベルが同時にブロックされるパーティの最大数に対応できる場合は、進行状況が保証されます。
</ul>
<b>終了。</b> フェイザーは、メソッド#isTerminated
を<使用してチェックできる em>終了</em> 状態になる可能性があります。 終了すると、すべての同期メソッドは、負の戻り値で示されているように、事前に待機せずに直ちに戻ります。 同様に、終了時に登録を試みると影響はありません。 終了は、戻りtrue
値のonAdvance
呼び出し時にトリガーされます。 既定の true
実装では、登録解除によって登録されたパーティの数が 0 になった場合に返されます。 次に示すように、フェイザーが固定回数の反復でアクションを制御する場合、現在のフェーズ番号がしきい値に達したときに終了を発生させるために、このメソッドをオーバーライドすると便利です。 メソッド #forceTermination
は、待機中のスレッドを突然解放して終了することもできます。
<b>階層化。</b> Phasers は <、競合を減らすために、階層>化</em> (ツリー構造で構築される) にすることができます。 それ以外の場合に高い同期競合コストが発生するパーティの数が多いフェイザーは、代わりにサブフェーズのグループが共通の親を共有するように設定できます。 これにより、操作ごとのオーバーヘッドが大きくなる場合でも、スループットが大幅に向上する可能性があります。
階層化されたフェイザーのツリーでは、親を持つ子フェイザーの登録と登録解除が自動的に管理されます。 子フェイザーの登録済みパーティの数が 0 以外になると (コンストラクターで#Phaser(Phaser,int)
確立されているように)、#register
#bulkRegister
子フェイザーがその親に登録されます。 登録されたパーティの数が呼び出し #arriveAndDeregister
の結果としてゼロになると、子フェイザーは親から登録解除されます。
<b>監視。</b> 同期メソッドは登録済みパーティによってのみ呼び出すことができますが、フェイザーの現在の状態は任意の呼び出し元によって監視される場合があります。 現在#getRegisteredParties
のフェーズ (#getPhase
) に到着した関係者は、#getArrivedParties
常に合計で存在します。 残りの (#getUnarrivedParties
) 当事者が到着すると、フェーズが進みます。 これらのメソッドによって返される値は一時的な状態を反映している可能性があるため、一般的に同期制御には役立ちません。 メソッド #toString
は、これらの状態クエリのスナップショットを、非公式の監視に便利な形式で返します。
メモリ整合性の影響: いずれかの形式の到着メソッド<より前のアクションは>、対応するフェーズの前/i> に進<み、onAdvance アクション (存在する場合)、フェーズの進行に続くアクションが発生します。
<b>使用例:</b>
A 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();
}}
一連のスレッドで特定の反復回数に対してアクションを繰り返し実行する 1 つの方法は、次のようにオーバーライド 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
を持つ Task クラスを想定しています。 呼び出した 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 ドキュメントjava.util.concurrent.Phaser
このページの一部は、Android オープンソース プロジェクトによって作成および共有され、クリエイティブ コモンズ 2.5 属性ライセンスに記載されている条件に従って使用される作業に基づく変更です。
コンストラクター
Phaser() |
最初に登録されたパーティ、親、および初期フェーズ番号 0 を持たない新しいフェイザーを作成します。 |
Phaser(Int32) |
指定された数の登録済みパーティ (親なし)、初期フェーズ番号 0 を使用して、新しいフェイザーを作成します。 |
Phaser(IntPtr, JniHandleOwnership) |
JNI オブジェクトのマネージド表現を作成するときに使用されるコンストラクター。ランタイムによって呼び出されます。 |
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() |
このオブジェクトのモニターで待機している 1 つのスレッドを起動します。 (継承元 Object) |
NotifyAll() |
このオブジェクトのモニターで待機しているすべてのスレッドを起動します。 (継承元 Object) |
OnAdvance(Int32, Int32) |
フェーズの進行が迫った場合にアクションを実行し、終了を制御するオーバーライド可能なメソッド。 |
Register() |
このフェイザーに新しい未接続のパーティーを追加します。 |
SetHandle(IntPtr, JniHandleOwnership) |
Handle プロパティを設定します。 (継承元 Object) |
ToArray<T>() |
再利用可能な同期バリア。機能 |
ToString() |
オブジェクトの文字列表現を返します。 (継承元 Object) |
UnregisterFromRuntime() |
再利用可能な同期バリア。機能 |
Wait() |
現在のスレッドが目覚めるまで待機させます。通常<は、通知<>/em> または <em>割り込み/em> を受け<取ります。 (継承元 Object) |
Wait(Int64) |
現在のスレッドが目覚めるまで待機します。通常<><は、通知/em> または <em>中断</em> によって、または一定のリアルタイムが経過するまで待機します。 (継承元 Object) |
Wait(Int64, Int32) |
現在のスレッドが目覚めるまで待機します。通常<><は、通知/em> または <em>中断</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) |
再利用可能な同期バリア。機能 |