Spec-Zone .ru
спецификации, руководства, описания, API
|
public class Phaser extends Object
CyclicBarrier
и CountDownLatch
но поддержка более гибкого использования. Регистрация. В отличие от случая для других барьеров, число сторон, зарегистрированных, чтобы синхронизироваться на фазовращателе, может измениться в течение долгого времени. В любое время могут быть зарегистрированы задачи (использующий методы register()
, bulkRegister(int)
, или формы конструкторов, устанавливающих начальные числа сторон), и дополнительно вычеркнутый из списка по любому прибытию (использование arriveAndDeregister()
). Как имеет место с большинством основных конструкций синхронизации, регистрация и deregistration влияют только на внутренние количества; они не устанавливают дальнейшую внутреннюю бухгалтерию, таким образом, задачи не могут запросить, регистрируются ли они. (Однако, можно представить такую бухгалтерию, разделяя этот класс на подклассы.)
Синхронизация. Как a CyclicBarrier
, a Phaser
может неоднократно ожидаться. Метод arriveAndAwaitAdvance()
имеет эффект, аналогичный CyclicBarrier.await
. У каждой генерации фазовращателя есть связанное фазовое число. Фазовое число запускается в нуле, и совершенствуется, когда все стороны достигают фазовращателя, повторяясь, чтобы обнулить после достижения Integer.MAX_VALUE
. Использование фазовых чисел включает независимому управлению действий по прибытию в фазовращатель и по ожиданию других через два вида методов, которые могут быть вызваны любой зарегистрированной стороной:
arrive()
и arriveAndDeregister()
прибытие записи. Эти методы не блокируют, но возвращают связанное число фазы прибытия; то есть, фазовое число фазовращателя, к которому применялось прибытие. Когда заключительная сторона для данной фазы прибывает, дополнительное действие выполняется и фазовые усовершенствования. Эти действия выполняются стороной, инициировавшей фазовое усовершенствование, и располагаются, переопределяя метод onAdvance(int, int)
, который также управляет завершением. Переопределение этого метода подобно, но более гибко чем, обеспечивая действие барьера для a CyclicBarrier
. awaitAdvance(int)
требует параметра, указывающего на число фазы прибытия, и возвращается, когда более фазовые усовершенствования к (или уже в), различная фаза. В отличие от подобного использования конструкций CyclicBarrier
, метод awaitAdvance
продолжает ожидать, даже если поток ожидания прерывается. Прерывистая и версии тайм-аута также доступны, но исключения, с которыми встречаются, в то время как задачи ожидают прерывистым образом, или с тайм-аутом не изменяют состояние фазовращателя. В случае необходимости можно выполнить любое связанное восстановление в пределах обработчиков тех исключений, часто после вызова forceTermination
. Фазовращатели могут также использоваться задачами, выполняющимися в a ForkJoinPool
, который гарантирует достаточный параллелизм, чтобы выполнить задачи, когда другие будут блокированы, ожидая фазы, чтобы совершенствоваться. Завершение. Фазовращатель может ввести состояние завершения, которое может быть проверено, используя метод isTerminated()
. После завершения все методы синхронизации сразу возвращаются, не ожидая усовершенствования, как обозначено отрицательным возвращаемым значением. Точно так же попытки зарегистрироваться после завершения не имеют никакого эффекта. Завершение инициировано когда вызов onAdvance
возвраты true
. Возвраты реализации по умолчанию true
если deregistration заставил число зарегистрированных сторон становиться нулем. Как иллюстрировано ниже, когда фазовращатели управляют действиями с постоянным числом итераций, часто удобно переопределить этот метод, чтобы вызвать завершение, когда текущее фазовое число достигает порога. Метод forceTermination()
также доступно, чтобы резко выпустить потоки ожидания и позволить им завершаться.
Разделение на уровни. Фазовращатели могут быть разделены на уровни (то есть, созданы в древовидных структурах) уменьшать конкуренцию. Фазовращатели с большими количествами сторон, которые иначе испытали бы тяжелые затраты конкуренции синхронизации, могут вместо этого быть установлены так, чтобы группы подфазовращателей совместно использовали общего родителя. Это может значительно увеличить пропускную способность даже при том, что она подвергается большим издержкам на работу.
В дереве разделенных на уровни фазовращателей регистрацией и deregistration дочерних фазовращателей с их родителем управляют автоматически. Всякий раз, когда число зарегистрированных сторон дочернего фазовращателя становится ненулевым (как установлено в Phaser(Phaser,int)
конструктор, register()
, или bulkRegister(int)
), дочерний фазовращатель регистрируется в его родителе. Всякий раз, когда число зарегистрированных сторон становится нулем как результатом вызова arriveAndDeregister()
, дочерний фазовращатель вычеркивается из списка от его родителя.
Контроль. В то время как методы синхронизации могут быть вызваны только зарегистрированными сторонами, текущее состояние фазовращателя может контролироваться любой вызывающей стороной. В любой данный момент есть getRegisteredParties()
стороны те, всего, который getArrivedParties()
достигли текущей фазы (getPhase()
). Когда остающееся (getUnarrivedParties()
) стороны прибывают, фазовые усовершенствования. Значения, возвращенные этими методами, могут отразить переходные состояния и так не вообще полезны для управления синхронизацией. Метод toString()
снимки возвратов этих состояние запрашивают в форме, удобной для неофициального контроля.
Демонстрационные использования:
A Phaser
может использоваться вместо a 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
задачи используя дерево фазовращателей, Вы могли использовать код следующей формы, принимая класс Задачи с конструктором, принимающим a Phaser
то, что это регистрируется в на конструкцию. После вызова build(new Task[n], 0, n, new Phaser())
, эти задачи могли тогда быть запущены, например подчиняясь пулу:
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
зависит, главным образом, от ожидаемых уровней синхронизации. Значение столь же низко как четыре может быть подходящим для чрезвычайно маленьких тел задачи на фазу (таким образом высокие показатели), или до сотен для чрезвычайно больших. Примечания реализации: Эта реализация ограничивает максимальное количество сторон к 65535. Попытки зарегистрировать дополнительные стороны приводят к IllegalStateException
. Однако, можете и следует создать разделенные на уровни фазовращатели, чтобы разместить произвольно большие группы участников.
Конструктор и Описание |
---|
Phaser()
Создает новый фазовращатель без первоначально зарегистрированных сторон, никакого родителя, и начальной фазы номер 0.
|
Phaser(int parties)
Создает новый фазовращатель с данным числом зарегистрированных неприбывших сторон, никакого родителя, и начальной фазы номер 0.
|
Phaser(Phaser parent)
Эквивалентный
Phaser(parent, 0) . |
Phaser(Phaser parent, int parties)
Создает новый фазовращатель с данным родителем и числом зарегистрированных неприбывших сторон.
|
Модификатор и Тип | Метод и Описание |
---|---|
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)
Добавляет данное число новых неприбывших сторон к этому фазовращателю.
|
void |
forceTermination()
Силы этот фазовращатель, чтобы ввести состояние завершения.
|
int |
getArrivedParties()
Возвращает число зарегистрированных сторон, которые достигли текущей фазы этого фазовращателя.
|
Фазовращатель |
getParent()
Возвращает родителя этого фазовращателя, или
null если ни один. |
int |
getPhase()
Возвращает текущее фазовое число.
|
int |
getRegisteredParties()
Возвращает число сторон, зарегистрированных в этом фазовращателе.
|
Фазовращатель |
getRoot()
Возвращает корневого предка этого фазовращателя, который является тем же самым как этим фазовращателем, если у этого нет никакого родителя.
|
int |
getUnarrivedParties()
Возвращает число зарегистрированных сторон, которые еще не достигли текущей фазы этого фазовращателя.
|
boolean |
isTerminated()
Возвраты
true если этот фазовращатель был завершен. |
protected boolean |
onAdvance(int phase, int registeredParties)
Переопределяемый метод, чтобы выполнить действие после нависшего фазового усовершенствования, и управлять завершением.
|
int |
register()
Добавляет новая неприбывшая сторона к этому фазовращателю.
|
Строка |
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
- пытаясь зарегистрировать больше чем максимальное поддерживаемое число сторонIllegalArgumentException
- если parties < 0
public int arrive()
Это - ошибка использования для незарегистрированной стороны, чтобы вызвать этот метод. Однако, эта ошибка может привести к IllegalStateException
только на некоторую последующую работу на этом фазовращателе, если когда-либо.
IllegalStateException
- если бы не завершенный и число неприбывших сторон стал бы отрицательнымpublic int arriveAndDeregister()
Это - ошибка использования для незарегистрированной стороны, чтобы вызвать этот метод. Однако, эта ошибка может привести к IllegalStateException
только на некоторую последующую работу на этом фазовращателе, если когда-либо.
IllegalStateException
- если бы не завершенный и число зарегистрированных или неприбывших сторон стал бы отрицательнымpublic int arriveAndAwaitAdvance()
awaitAdvance(arrive())
. Если Вы должны ждать с прерыванием или тайм-аутом, можно расположить это с аналогичной конструкцией, используя одну из других форм awaitAdvance
метод. Если вместо этого Вы должны вычеркнуть из списка по прибытию, использовать awaitAdvance(arriveAndDeregister())
. Это - ошибка использования для незарегистрированной стороны, чтобы вызвать этот метод. Однако, эта ошибка может привести к IllegalStateException
только на некоторую последующую работу на этом фазовращателе, если когда-либо.
IllegalStateException
- если бы не завершенный и число неприбывших сторон стал бы отрицательным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
- a 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
если этот фазовращатель должен завершитьсяpublic String toString()
"phase = "
сопровождаемый фазовым числом, "parties = "
сопровождаемый числом зарегистрированных сторон, и "arrived = "
сопровождаемый числом прибывших сторон.
Для дальнейшей ссылки API и документации разработчика, см.
Авторское право © 1993, 2011, Oracle и/или его филиалы. Все права защищены.