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.