|
||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||
java.lang.Objectjsr166y.Phaser
public class Phaser
A reusable synchronization barrier, similar in functionality to a
CyclicBarrier and
CountDownLatch
but supporting more flexible usage.
Integer.MAX_VALUE).
arriveAndAwaitAdvance has effect analogous to
CyclicBarrier.await. However, Phasers separate two
aspects of coordination, that may also be invoked independently:
arrive and
arriveAndDeregister do not block, but return
the phase value current upon entry to the method.
awaitAdvance requires an
argument indicating the entry phase, and returns when the
barrier advances to a new phase.
onAdvance, that also controls termination.
Overriding this method may be used to similar but more flexible
effect as providing a barrier action to a CyclicBarrier.
onAdvance method that is invoked each time the
barrier is about to be tripped. When a Phaser is controlling an
action with a fixed number of iterations, it is often convenient to
override this method to cause termination when the current phase
number reaches a threshold. Method forceTermination is also
available to abruptly release waiting threads and allow them to
terminate.
awaitAdvance continues to wait even if
the waiting thread is interrupted. And unlike the case in
CyclicBarriers, exceptions encountered while tasks wait
interruptibly or with timeout do not change the state of the
barrier. If necessary, you can perform any associated recovery
within handlers of those exceptions, often after invoking
forceTermination.
Sample usages:
A Phaser may be used instead of a CountDownLatch to control
a one-shot action serving a variable number of parties. The typical
idiom is for the method setting this up to first register, then
start the actions, then deregister, as in:
void runTasks(List<Runnable> list) {
final Phaser phaser = new Phaser(1); // "1" to register self
for (Runnable r : list) {
phaser.register();
new Thread() {
public void run() {
phaser.arriveAndAwaitAdvance(); // await all creation
r.run();
phaser.arriveAndDeregister(); // signal completion
}
}.start();
}
doSomethingOnBehalfOfWorkers();
phaser.arrive(); // allow threads to start
int p = phaser.arriveAndDeregister(); // deregister self ...
p = phaser.awaitAdvance(p); // ... and await arrival
otherActions(); // do other things while tasks execute
phaser.awaitAdvance(p); // await final completion
}
One way to cause a set of threads to repeatedly perform actions
for a given number of iterations is to override onAdvance:
void startTasks(List<Runnable> list, final int iterations) {
final Phaser phaser = new Phaser() {
public boolean onAdvance(int phase, int registeredParties) {
return phase >= iterations || registeredParties == 0;
}
};
phaser.register();
for (Runnable r : list) {
phaser.register();
new Thread() {
public void run() {
do {
r.run();
phaser.arriveAndAwaitAdvance();
} while(!phaser.isTerminated();
}
}.start();
}
phaser.arriveAndDeregister(); // deregister self, don't wait
}
To create a set of tasks using a tree of Phasers, you could use code of the following form, assuming a Task class with a constructor accepting a Phaser that it registers for upon construction:
void build(Task[] actions, int lo, int hi, Phaser b) {
int step = (hi - lo) / TASKS_PER_PHASER;
if (step > 1) {
int i = lo;
while (i < hi) {
int r = Math.min(i + step, hi);
build(actions, i, r, new Phaser(b));
i = r;
}
}
else {
for (int i = lo; i < hi; ++i)
actions[i] = new Task(b);
// assumes new Task(b) performs b.register()
}
}
// .. initially called, for n tasks via
build(new Task[n], 0, n, new Phaser());
The best value of TASKS_PER_PHASER depends mainly on
expected barrier synchronization rates. A value as low as four may
be appropriate for extremely small per-barrier task bodies (thus
high rates), or up to hundreds for extremely large ones.
Implementation notes: This implementation restricts the maximum number of parties to 65535. Attempts to register additional parties result in IllegalStateExceptions. However, you can and should create tiered phasers to accommodate arbitrarily large sets of participants.
| Constructor Summary | |
|---|---|
Phaser()
Creates a new Phaser without any initially registered parties, initial phase number 0, and no parent. |
|
Phaser(int parties)
Creates a new Phaser with the given numbers of registered unarrived parties, initial phase number 0, and no parent. |
|
Phaser(Phaser parent)
Creates a new Phaser with the given parent, without any initially registered parties. |
|
Phaser(Phaser parent,
int parties)
Creates a new Phaser with the given parent and numbers of registered unarrived parties. |
|
| Method Summary | |
|---|---|
int |
arrive()
Arrives at the barrier, but does not wait for others. |
int |
arriveAndAwaitAdvance()
Arrives at the barrier and awaits others. |
int |
arriveAndDeregister()
Arrives at the barrier, and deregisters from it, without waiting for others. |
int |
awaitAdvance(int phase)
Awaits the phase of the barrier to advance from the given value, or returns immediately if argument is negative or this barrier is terminated. |
int |
awaitAdvanceInterruptibly(int phase)
Awaits the phase of the barrier to advance from the given value, or returns immediately if argument is negative or this barrier is terminated, or throws InterruptedException if interrupted while waiting. |
int |
awaitAdvanceInterruptibly(int phase,
long timeout,
TimeUnit unit)
Awaits the phase of the barrier to advance from the given value or the given timeout elapses, or returns immediately if argument is negative or this barrier is terminated. |
int |
bulkRegister(int parties)
Adds the given number of new unarrived parties to this phaser. |
void |
forceTermination()
Forces this barrier to enter termination state. |
int |
getArrivedParties()
Returns the number of parties that have arrived at the current phase of this barrier. |
Phaser |
getParent()
Returns the parent of this phaser, or null if none. |
int |
getPhase()
Returns the current phase number. |
int |
getRegisteredParties()
Returns the number of parties registered at this barrier. |
Phaser |
getRoot()
Returns the root ancestor of this phaser, which is the same as this phaser if it has no parent. |
int |
getUnarrivedParties()
Returns the number of registered parties that have not yet arrived at the current phase of this barrier. |
boolean |
hasPhase(int phase)
Returns true if the current phase number equals the given phase. |
boolean |
isTerminated()
Returns true if this barrier has been terminated. |
protected boolean |
onAdvance(int phase,
int registeredParties)
Overridable method to perform an action upon phase advance, and to control termination. |
int |
register()
Adds a new unarrived party to this phaser. |
String |
toString()
Returns a string identifying this phaser, as well as its state. |
| Methods inherited from class java.lang.Object |
|---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
| Constructor Detail |
|---|
public Phaser()
public Phaser(int parties)
parties - the number of parties required to trip barrier.
IllegalArgumentException - if parties less than zero
or greater than the maximum number of parties supported.public Phaser(Phaser parent)
parent - the parent phaser.
public Phaser(Phaser parent,
int parties)
parent - the parent phaser.parties - the number of parties required to trip barrier.
IllegalArgumentException - if parties less than zero
or greater than the maximum number of parties supported.| Method Detail |
|---|
public int register()
IllegalStateException - if attempting to register more
than the maximum supported number of parties.public int bulkRegister(int parties)
parties - the number of parties required to trip barrier.
IllegalStateException - if attempting to register more
than the maximum supported number of parties.public int arrive()
awaitAdvance(int)).
IllegalStateException - if not terminated and the number
of unarrived parties would become negative.public int arriveAndDeregister()
IllegalStateException - if not terminated and the number
of registered or unarrived parties would become negative.public int arriveAndAwaitAdvance()
awaitAdvance(arrive()). If you instead need to
await with interruption of timeout, and/or deregister upon
arrival, you can arrange them using analogous constructions.
IllegalStateException - if not terminated and the number
of unarrived parties would become negative.public int awaitAdvance(int phase)
phase - the phase on entry to this method
public int awaitAdvanceInterruptibly(int phase)
throws InterruptedException
phase - the phase on entry to this method
InterruptedException - if thread interrupted while waiting
public int awaitAdvanceInterruptibly(int phase,
long timeout,
TimeUnit unit)
throws InterruptedException,
TimeoutException
phase - the phase on entry to this method
InterruptedException - if thread interrupted while waiting
TimeoutException - if timed out while waitingpublic void forceTermination()
public final int getPhase()
Integer.MAX_VALUE, after which it restarts at
zero. Upon termination, the phase number is negative.
public final boolean hasPhase(int phase)
true if the current phase number equals the given phase.
phase - the phase
true if the current phase number equals the given phasepublic int getRegisteredParties()
public int getArrivedParties()
public int getUnarrivedParties()
public Phaser getParent()
public Phaser getRoot()
public boolean isTerminated()
true if this barrier has been terminated.
true if this barrier has been terminated
protected boolean onAdvance(int phase,
int registeredParties)
isTerminated will
return true.
The default version returns true when the number of registered parties is zero. Normally, overrides that arrange termination for other reasons should also preserve this property.
You may override this method to perform an action with side
effects visible to participating tasks, but it is in general
only sensible to do so in designs where all parties register
before any arrive, and all awaitAdvance at each phase.
Otherwise, you cannot ensure lack of interference. In
particular, this method may be invoked more than once per
transition if other parties successfully register while the
invocation of this method is in progress, thus postponing the
transition until those parties also arrive, re-triggering this
method.
phase - the phase number on entering the barrierregisteredParties - the current number of registered parties
true if this barrier should terminatepublic String toString()
"phase = " followed by the phase number, "parties = "
followed by the number of registered parties, and "arrived = " followed by the number of arrived parties.
toString in class Object
|
||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD | |||||||