Spec-Zone .ru
спецификации, руководства, описания, API
|
|
Java™ Platform Standard Ed. 7 DRAFT ea-b118 |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object java.util.concurrent.Phaser
public class Phaser extends Object
A reusable synchronization barrier, similar in functionality to
CyclicBarrier
and
CountDownLatch
but supporting more flexible usage.
Registration. Unlike the case for other barriers, the
number of parties registered to synchronize on a phaser
may vary over time. Tasks may be registered at any time (using
methods register()
, bulkRegister(int)
, or forms of
constructors establishing initial numbers of parties), and
optionally deregistered upon any arrival (using arriveAndDeregister()
). As is the case with most basic
synchronization constructs, registration and deregistration affect
only internal counts; they do not establish any further internal
bookkeeping, so tasks cannot query whether they are registered.
(However, you can introduce such bookkeeping by subclassing this
class.)
Synchronization. Like a CyclicBarrier
, a Phaser
may be repeatedly awaited. Method arriveAndAwaitAdvance()
has effect analogous to CyclicBarrier.await
. Each
generation of a Phaser
has an associated phase number. The
phase number starts at zero, and advances when all parties arrive
at the barrier, wrapping around to zero after reaching Integer.MAX_VALUE
. The use of phase numbers enables independent
control of actions upon arrival at a barrier and upon awaiting
others, via two kinds of methods that may be invoked by any
registered party:
arrive()
and
arriveAndDeregister()
record arrival at a
barrier. These methods do not block, but return an associated
arrival phase number; that is, the phase number of
the barrier to which the arrival applied. When the final
party for a given phase arrives, an optional barrier action
is performed and the phase advances. Barrier actions,
performed by the party triggering a phase advance, are
arranged by overriding method onAdvance(int, int)
,
which also controls termination. Overriding this method is
similar to, but more flexible than, providing a barrier
action to a CyclicBarrier
.
awaitAdvance(int)
requires an
argument indicating an arrival phase number, and returns when
the barrier advances to (or is already at) a different phase.
Unlike similar constructions using CyclicBarrier
,
method awaitAdvance
continues to wait even if the
waiting thread is interrupted. Interruptible and timeout
versions are also available, but 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
. Phasers may
also be used by tasks executing in a ForkJoinPool
,
which will ensure sufficient parallelism to execute tasks
when others are blocked waiting for a phase to advance.
Termination. A Phaser
may enter a
termination state in which all synchronization methods
immediately return without updating phaser state or waiting for
advance, and indicating (via a negative phase value) that execution
is complete. Termination is triggered when an invocation of onAdvance
returns true
. As illustrated below, when
phasers control actions 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.
Tiering. Phasers may be tiered (i.e., arranged in tree structures) to reduce contention. Phasers with large numbers of parties that would otherwise experience heavy synchronization contention costs may instead be set up so that groups of sub-phasers share a common parent. This may greatly increase throughput even though it incurs greater per-operation overhead.
Monitoring. While synchronization methods may be invoked
only by registered parties, the current state of a phaser may be
monitored by any caller. At any given moment there are getRegisteredParties()
parties in total, of which getArrivedParties()
have arrived at the current phase (getPhase()
). When the remaining (getUnarrivedParties()
)
parties arrive, the phase advances. The values returned by these
methods may reflect transient states and so are not in general
useful for synchronization control. Method toString()
returns snapshots of these state queries in a form convenient for
informal monitoring.
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> tasks) {
final Phaser phaser = new Phaser(1); // "1" to register self
// create and start threads
for (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();
}
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> 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
}
If the main task must later await termination, it
may re-register and then execute a similar loop:
// ...
phaser.register();
while (!phaser.isTerminated())
phaser.arriveAndAwaitAdvance();
Related constructions may be used to await particular phase numbers
in contexts where you are sure that the phase will never wrap around
Integer.MAX_VALUE
. For example:
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();
}
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 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(actions, i, j, new Phaser(ph));
}
} else {
for (int i = lo; i < hi; ++i)
actions[i] = new Task(ph);
// assumes new Task(ph) performs ph.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 IllegalStateException
. However, you can and
should create tiered phasers to accommodate arbitrarily large sets
of participants.
Constructor and Description |
---|
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. |
Modifier and Type | Method and Description |
---|---|
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 phase value, returning immediately if the current phase of the barrier is not equal to the given phase value or this barrier is terminated. |
int |
awaitAdvanceInterruptibly(int phase)
Awaits the phase of the barrier to advance from the given phase value, throwing InterruptedException if interrupted
while waiting, or returning immediately if the current phase of
the barrier is not equal to the given phase value or this
barrier is terminated. |
int |
awaitAdvanceInterruptibly(int phase,
long timeout,
TimeUnit unit)
Awaits the phase of the barrier to advance from the given phase value or the given timeout to elapse, throwing InterruptedException if interrupted while waiting, or
returning immediately if the current phase of the barrier is
not equal to the given phase value 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 registered 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 |
isTerminated()
Returns true if this barrier has been terminated. |
protected boolean |
onAdvance(int phase,
int registeredParties)
Overridable method to perform an action upon impending 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 barrierIllegalArgumentException
- if parties less than zero
or greater than the maximum number of parties supportedpublic Phaser(Phaser parent)
parent
- the parent phaserpublic Phaser(Phaser parent, int parties)
parent
- the parent phaserparties
- the number of parties required to trip barrierIllegalArgumentException
- if parties less than zero
or greater than the maximum number of parties supportedMethod Detail |
---|
public int register()
IllegalStateException
- if attempting to register more
than the maximum supported number of partiespublic int bulkRegister(int parties)
parties
- the number of parties required to trip barrierIllegalStateException
- if attempting to register more
than the maximum supported number of partiespublic int arrive()
awaitAdvance(int)
). It is an
unenforced usage error for an unregistered party to invoke this
method.
IllegalStateException
- if not terminated and the number
of unarrived parties would become negativepublic int arriveAndDeregister()
IllegalStateException
- if not terminated and the number
of registered or unarrived parties would become negativepublic int arriveAndAwaitAdvance()
awaitAdvance(arrive())
. If you need to await with
interruption or timeout, you can arrange this with an analogous
construction using one of the other forms of the awaitAdvance
method. If instead you need to deregister upon arrival use
arriveAndDeregister
. It is an unenforced usage error
for an unregistered party to invoke this method.
IllegalStateException
- if not terminated and the number
of unarrived parties would become negativepublic int awaitAdvance(int phase)
phase
- an arrival phase number, or negative value if
terminated; this argument is normally the value returned by a
previous call to arrive
or its variantspublic int awaitAdvanceInterruptibly(int phase) throws InterruptedException
InterruptedException
if interrupted
while waiting, or returning immediately if the current phase of
the barrier is not equal to the given phase value or this
barrier is terminated. It is an unenforced usage error for an
unregistered party to invoke this method.
phase
- an arrival phase number, or negative value if
terminated; this argument is normally the value returned by a
previous call to arrive
or its variantsInterruptedException
- if thread interrupted while waitingpublic int awaitAdvanceInterruptibly(int phase, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException
InterruptedException
if interrupted while waiting, or
returning immediately if the current phase of the barrier is
not equal to the given phase value or this barrier is
terminated. It is an unenforced usage error for an
unregistered party to invoke this method.
phase
- an arrival phase number, or negative value if
terminated; this argument is normally the value returned by a
previous call to arrive
or its variantstimeout
- how long to wait before giving up, in units of
unit
unit
- a TimeUnit
determining how to interpret the
timeout
parameterInterruptedException
- if thread interrupted while waitingTimeoutException
- 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 int getRegisteredParties()
public int getArrivedParties()
public int getUnarrivedParties()
public Phaser getParent()
null
if none.
null
if nonepublic Phaser getRoot()
public boolean isTerminated()
true
if this barrier has been terminated.
true
if this barrier has been terminatedprotected boolean onAdvance(int phase, int registeredParties)
true
, then, rather than advance the phase number, this barrier
will be set to a final termination state, and subsequent calls
to isTerminated()
will return true. Any (unchecked)
Exception or Error thrown by an invocation of this method is
propagated to the party attempting to trip the barrier, in
which case no advance occurs.
The arguments to this method provide the state of the phaser
prevailing for the current transition. (When called from within
an implementation of onAdvance
the values returned by
methods such as getPhase
may or may not reliably
indicate the state to which this transition applies.)
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 only sensible
to do so in designs where all parties register before any
arrive, and all awaitAdvance(int)
at each phase.
Otherwise, you cannot ensure lack of interference from other
parties during the invocation of this method. Additionally,
method onAdvance
may be invoked more than once per
transition if registrations are intermixed with arrivals.
phase
- the phase number on entering the barrierregisteredParties
- the current number of registered partiestrue
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
|
Java™ Platform Standard Ed. 7 DRAFT ea-b118 |
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
Copyright © 1993, 2010, Oracle Corporation. All rights reserved.