public class Phaser extends Object
CyclicBarrier和
CountDownLatch相似但支持更灵活的使用。
登记。不像其他障碍的情况下,注册同步移相器聚会的人数可能会随时间而变化。任务可以在任何时间注册(使用构造函数创建初始数字register()方方法,bulkRegister(int),或形式),和可选的撤销在任何到达(使用arriveAndDeregister())。是最基本的同步结构的情况下,注册和注销登记只影响内部计数;他们没有建立任何内部记账,所以任务不能查询是否注册。(然而,你可以介绍通过继承这个类。这种记账)
同步。像CyclicBarrier,一Phaser可以重复等待。方法arriveAndAwaitAdvance()效果类似于CyclicBarrier.await。每一代的移相器有一个相关的相数。相数从零开始,提出当各方到达相位,缠绕到零后达到Integer.MAX_VALUE。相数的使用使行动到达移相器在等待他人的独立控制,通过两种方法可以调用任何注册方:
arrive()和arriveAndDeregister()记录到达。这些方法不会阻止,但返回一个相关的到来相数;即,相数的移相器,到达应用。当一个给定阶段的最后一方到达时,一个可选的动作和相位的进步。这些行动是由党的触发相位超前进行,并通过重写方法onAdvance(int, int)排列,也控制了终止。重写此方法类似,但更灵活,一CyclicBarrier提供屏障作用。awaitAdvance(int)需要参数指示到达相数,和返回时的相位的进步(或已经)不同的阶段。不同于类似结构的使用方法CyclicBarrier,awaitAdvance继续即使等待线程被中断等。中断和超时版本也可以,但例外时遇到的任务等interruptibly或超时不改变相位的状态。如果有必要,你可以在这些异常处理程序执行任何相关的恢复,通常在调用forceTermination。移相器也可以在ForkJoinPool执行任务,这将保证足够的并行执行任务时别人封锁等待一个阶段推进。终止.移相器可以进入一个终止状态,可以使用的方法isTerminated()检查。一旦终止,所有同步方法立即返回而不等待前进,由负的返回值表示。同样,试图注册终止时,没有任何效果。终止被触发时调用的返回true onAdvance。默认的实现返回true如果注销造成登记的政党数量为零。如下图所示,当移相器具有固定数量的迭代控制行动,通常是很方便的重写此方法以原因终止,当电流相数达到一个阈值。方法forceTermination()也可突然释放等待的线程,并允许他们终止。
Tiering。移相器可以分层(即,在树结构)以减少争用。移相器有大量的当事人,否则经验重同步竞争成本可以这样设置子炮组共享一个共同的父。这可能会大大增加吞吐量,即使它会带来更大的每操作开销。
在一棵树的分层炮、注册和注销的父母孩子移相器是自动管理。每当一个孩子Phaser注册当事人人数变为非零(在Phaser(Phaser,int)构造函数,建立register(),或bulkRegister(int)),孩子与家长注册移相器。每当注册政党的数目为零的arriveAndDeregister()调用的结果,孩子是从其母公司注销移相器。
监测。而同步方法只能在注册方调用,一个移相器的当前状态,可以由任何人监视。在任何给定的时刻,共有getRegisteredParties()聚会,其中getArrivedParties()已经到达电流相位(getPhase())。当剩下的(getUnarrivedParties())方到,相的研究进展。这些方法返回的值可能反映了短暂的状态,所以不在一般的有用的同步控制。方法toString()返回一个方便的非正式的监督形式的这些状态查询快照。
示例用法:
一个Phaser可以用来代替一个CountDownLatch控制一一拍的动作为政党数目可变的。典型的成语的方法设置的先登记,然后开始行动,然后注销,如:
void runTasks(List<Runnable> tasks) {
final Phaser phaser = new Phaser(1); // "1" to register self
// create and start threads
for (final Runnable task : tasks) {
phaser.register();
new Thread() {
public void run() {
phaser.arriveAndAwaitAdvance(); // await all creation
task.run();
}
}.start();
}
// allow threads to start and deregister self
phaser.arriveAndDeregister();
}
使一组线程反复执行一个给定的迭代次数的一个方法是重写onAdvance行动:
void startTasks(List<Runnable> tasks, final int iterations) {
final Phaser phaser = new Phaser() {
protected boolean onAdvance(int phase, int registeredParties) {
return phase >= iterations || registeredParties == 0;
}
};
phaser.register();
for (final Runnable task : tasks) {
phaser.register();
new Thread() {
public void run() {
do {
task.run();
phaser.arriveAndAwaitAdvance();
} while (!phaser.isTerminated());
}
}.start();
}
phaser.arriveAndDeregister(); // deregister self, don't wait
}如果主要任务必须等待终止后,可重新登记,然后执行一个类似的循环:
// ...
phaser.register();
while (!phaser.isTerminated())
phaser.arriveAndAwaitAdvance();
相关结构可以用来等待的地方,你确定这个阶段不会缠绕Integer.MAX_VALUE特定的相数。例如:
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())调用后,这些任务就可以开始,例如通过提交一个池:
TASKS_PER_PHASER最好的价值主要取决于预期的同步率。一个值低至四,可能是适当的非常小的每个阶段的任务机构(因此高利率),或高达数百个非常大的。
实现注意事项:实施限制当事人的最大数目65535。试图登记追加当事人造成IllegalStateException。然而,你可以创建分层的移相器容纳参与者任意大集合。
| Constructor and Description |
|---|
Phaser()
创建无初始登记的政党,一个新的相位没有父母,和初始相位数0。
|
Phaser(int parties)
创建和注册unarrived聚会,一定数量的新的相位没有父母,和初始相位数0。
|
Phaser(Phaser parent)
相当于
Phaser(parent, 0)。
|
Phaser(Phaser parent, int parties)
创建具有给定的父和注册unarrived方数新的移相器。
|
| Modifier and Type | Method and Description |
|---|---|
int |
arrive()
到这个相位,无需等待别人来。
|
int |
arriveAndAwaitAdvance()
来到这个相位和等待别人。
|
int |
arriveAndDeregister()
来到这个相位和撤销它没有等待别人来。
|
int |
awaitAdvance(int phase)
等待着这个相位的相位提前从给定的相位值,立即返回如果相电流不等于给定值或终止这种移相器的相。
|
int |
awaitAdvanceInterruptibly(int phase)
等待着这个相位的相位提前从给定的相位值,扔
InterruptedException如果中断等待,或立即返回如果相电流不等于给定值或终止这种移相器的相。
|
int |
awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit)
等待着这个相位的相位提前从给定的相位值或给定的超时时间,扔
InterruptedException如果中断等待,或立即返回如果相电流不等于给定值或终止这种移相器的相。
|
int |
bulkRegister(int parties)
增加了新的unarrived方一定数量的本相。
|
void |
forceTermination()
军队这相位进入终止状态。
|
int |
getArrivedParties()
返回到了这个相位的电流相位,注册方数。
|
Phaser |
getParent()
返回此相位的父母,或
null如果没有。
|
int |
getPhase()
返回当前的相数。
|
int |
getRegisteredParties()
返回在这个相位注册政党的数目。
|
Phaser |
getRoot()
返回此相位的根祖,这是这个相位如果没有父一样。
|
int |
getUnarrivedParties()
返回尚未到达这个相位的电流相位注册方数。
|
boolean |
isTerminated()
返回
true如果这个相位已经终止。
|
protected boolean |
onAdvance(int phase, int registeredParties)
在即将到来的相位提前执行一个动作可重写的方法,和控制终端。
|
int |
register()
增加了一个新的unarrived党这个相位。
|
String |
toString()
返回一个字符串识别这种移相器,以及其状态。
|
public Phaser()
public Phaser(int parties)
parties -需要前进到下一个阶段的当事人人数
IllegalArgumentException小于零或大于最大数量的政党支持
public Phaser(Phaser parent)
Phaser(parent, 0)。
parent -母移相器
public Phaser(Phaser parent, int parties)
parent -母移相器
parties -需要前进到下一个阶段的当事人人数
IllegalArgumentException小于零或大于最大数量的政党支持
public int register()
onAdvance(int, int)在进步,这种方法可能会等待其完成后。如果这个相位有一个家长,这相位之前没有登记的政党,这个孩子相位也与其母注册。如果这个相位终止,尝试登记没有影响,和一个负的返回值。
IllegalStateException如果试图登记超过最大支持的政党数目
public int bulkRegister(int parties)
onAdvance(int, int)在进步,这种方法可能会等待其完成后。如果这个相位有一个家长,以及当事人的已知数是大于零,这相位之前没有登记的政党,这个孩子相位也与其母注册。如果这个相位终止,尝试登记没有影响,和一个负的返回值。
parties需要进入下一阶段的当事人追加的数量
IllegalStateException如果试图登记超过最大支持的政党数目
parties < 0
IllegalArgumentException
public int arrive()
调用此方法是未注册方的使用错误。然而,这样的错误可能导致一个IllegalStateException只对一些后续操作在这个相位,如果有。
IllegalStateException -如果没有终止和unarrived聚会的人数会成为负
public int arriveAndDeregister()
调用此方法是未注册方的使用错误。然而,这样的错误可能导致一个IllegalStateException只对一些后续操作在这个相位,如果有。
IllegalStateException -如果不是终止注册或unarrived聚会的人数会成为负
public int arriveAndAwaitAdvance()
awaitAdvance(arrive())。如果你需要等待中断或暂停,你可以安排这用另一个的
awaitAdvance形式类似的施工方法。如果您需要注销时,
awaitAdvance(arriveAndDeregister())
调用此方法是未注册方的使用错误。然而,这样的错误可能导致一个IllegalStateException只对一些后续操作在这个相位,如果有。
IllegalStateException -如果没有终止和unarrived聚会的人数会成为负
public int awaitAdvance(int phase)
phase -到达相数,或负价值如果终止;这种说法通常是价值由以前调用
arrive或
arriveAndDeregister返回。
public int awaitAdvanceInterruptibly(int phase)
throws InterruptedException
InterruptedException如果中断等待,或立即返回如果相电流不等于给定值或终止这种移相器的相。
phase -到达相数,或负价值如果终止;这种说法通常是价值由以前调用
arrive或
arriveAndDeregister返回。
InterruptedException如果线程中断等待
public int awaitAdvanceInterruptibly(int phase,
long timeout,
TimeUnit unit)
throws InterruptedException,
TimeoutException
InterruptedException如果中断等待,或立即返回如果相电流不等于给定值或终止这种移相器的相。
phase -到达相数,或负价值如果终止;这种说法通常是价值由以前调用
arrive或
arriveAndDeregister返回。
timeout -多久才放弃等待,在单位
unit
unit -
TimeUnit确定如何解释
timeout参数
InterruptedException如果线程中断等待
TimeoutException如果超时等待
public void forceTermination()
public final int getPhase()
Integer.MAX_VALUE,然后重新启动在零。一旦终止,相数是负的,在这种情况下,当前期终止前可通过
getPhase() + Integer.MIN_VALUE。
public int getRegisteredParties()
public int getArrivedParties()
public int getUnarrivedParties()
public Phaser getParent()
null如果没有。
null如果没有
public Phaser getRoot()
public boolean isTerminated()
true如果这个相位已经终止。
true如果这个相位已经终止
protected boolean onAdvance(int phase,
int registeredParties)
true,这个相位将在推进最后的终止状态,并随后调用
isTerminated()将返回true。有(没有)异常或错误的方法调用被传递到党试图推进这一相位,在这种情况下,没有提前发生。
这个方法的参数提供的相位的电流转换的普遍状态。调用的到来,登记的影响,等方法对这相位在onAdvance是不不应该依赖。
如果这个相位是一个分层的移相器的一员,那么onAdvance只是每推进其根移相器调用。
支持最常见的使用情况下,此方法的默认实现返回true当注册政党数量为零的一方arriveAndDeregister调用结果。您可以禁用此行为,从而能够在未来延续注册,通过重写此方法总是返回false:
Phaser phaser = new Phaser() {
protected boolean onAdvance(int phase, int parties) { return false; }
}
phase -进入这个方法的电流相数,在这之前是先进的移相器
registeredParties -目前登记的政党数量
true如果这个相位应该终止
Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2014, Oracle and/or its affiliates. All rights reserved.