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> 与 a 一 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> A 分阶段器可能进入 <em>终止</em> 状态,可以使用方法 #isTerminated
进行检查。 终止后,所有同步方法会立即返回,无需等待提前,由负返回值指示。 同样,在终止时注册尝试不起作用。 当调用 onAdvance
返回 true
时触发终止。 如果取消注册导致注册方数变为零,则默认实现将返回 true
。 如下所示,当分阶段器控制具有固定迭代数的操作时,当当前阶段数达到阈值时,重写此方法通常会方便导致终止。 方法 #forceTermination
还可用于突然释放等待的线程,并允许它们终止。
<b>分层。</b> 分阶段器可以是 <em>分层</em> (即,在树结构中构造)以减少争用。 可以设置具有大量参与方的分阶段程序,否则可能会遇到大量同步争用成本,以便子分阶段组共享公共父级。 即使每个操作开销更大,这也可能大大增加吞吐量。
在分层分阶段器的树中,会自动管理其父阶段器的注册和取消注册。 每当子分阶段器的注册方数变为非零(如构造函数中 #Phaser(Phaser,int)
建立的) #register
或 #bulkRegister
子分阶段器时,子分阶段器将注册到其父级。 每当注册方数因调用 #arriveAndDeregister
而变为零时,子阶段程序将从其父级取消注册。
<b>监视。</b> 虽然同步方法只能由注册方调用,但任何调用方都可以监视分阶段器的当前状态。 在任何给定时刻,都有 #getRegisteredParties
各方,其中 #getArrivedParties
已进入当前阶段(#getPhase
)。 当剩余的(#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();
}}
导致一组线程对给定次数的迭代重复执行操作的一种方法是重写 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 对象的托管表示形式时使用的构造函数;由运行时调用。 |
Phaser(Phaser) |
等效于 |
Phaser(Phaser, Int32) |
使用给定的父级和注册未参与方数创建新的分阶段程序。 |
属性
ArrivedParties |
返回已到达此分阶段的当前阶段的已注册参与方数。 |
Class |
返回此 |
Handle |
基础 Android 实例的句柄。 (继承自 Object) |
IsTerminated |
如果此分阶段器已终止,则返回 |
JniIdentityHashCode |
可重用的同步屏障,与功能 |
JniPeerMembers |
可重用的同步屏障,与功能 |
Parent |
返回此分阶段器的父级,如果没有 |
PeerReference |
可重用的同步屏障,与功能 |
Phase |
返回当前阶段号。 |
RegisteredParties |
返回在此阶段注册的参与方数。 |
Root |
返回此分阶段器的根上级,如果该阶段器没有父级,则与此分阶段器相同。 |
ThresholdClass |
此 API 支持 Mono for Android 基础结构,不打算直接从代码使用。 |
ThresholdType |
此 API 支持 Mono for Android 基础结构,不打算直接从代码使用。 |
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 通知/em> 或 <em>interrupted</em>。<>< (继承自 Object) |
Wait(Int64) |
使当前线程等待直到唤醒,通常是通过 <em>通知</em> 或 <em interrupted</em>>,或直到经过一定数量的实时。 (继承自 Object) |
Wait(Int64, Int32) |
使当前线程等待直到唤醒,通常是通过 <em>通知</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) |
可重用的同步屏障,与功能 |