Класс CountedCompleter<T>
- Параметры типа:
T- тип результата завершающего объекта
- Все реализуемые интерфейсы:
Serializable, Future<T>
public abstract class CountedCompleter<T> extends ForkJoinTask<T>
ForkJoinTask с действием завершения, выполняемым при срабатывании, когда не остается ожидающих действий. CountedCompleter обычно более устойчивы к задержкам и блокировкам подзадач, чем другие разновидности ForkJoinTask, но менее интуитивны в программировании. CountedCompleter используются аналогично другим компонентам, основанным на завершении (например, CompletionHandler), за исключением того, что для запуска действия завершения onCompletion(CountedCompleter) может потребоваться несколько ожидающих завершений, а не одно. Если не задано иное, счетчик ожидающих действий изначально равен нулю, но его можно (атомарно) изменить с помощью методов setPendingCount(int), addToPendingCount(int) и compareAndSetPendingCount(int, int). При вызове tryComplete(), если счетчик ожидающих действий не равен нулю, он уменьшается; в противном случае выполняется действие завершения, и, если у этого завершающего объекта есть собственный завершающий объект, процесс продолжается с ним. Как и в случае связанных компонентов синхронизации, таких как Phaser и Semaphore, эти методы влияют только на внутренние счетчики; они не ведут никакого дополнительного внутреннего учета. В частности, идентификаторы ожидающих задач не сохраняются. Как показано ниже, при необходимости можно создавать подклассы, которые регистрируют некоторые или все ожидающие задачи либо их результаты. Ниже также показаны вспомогательные методы, позволяющие настраивать обходы завершения. Однако, поскольку CountedCompleter предоставляют только базовые механизмы синхронизации, может быть полезно создать дополнительные абстрактные подклассы, поддерживающие связи, поля и дополнительные методы, необходимые для набора связанных вариантов использования. Конкретный класс CountedCompleter должен определять метод compute(), который в большинстве случаев (как показано ниже) должен вызывать tryComplete() один раз перед возвратом. Класс также может переопределить метод onCompletion(CountedCompleter) для выполнения действия при штатном завершении и метод onExceptionalCompletion(Throwable, CountedCompleter) для выполнения действия при возникновении любого исключения.
Чаще всего CountedCompleter не возвращают результаты; в этом случае их обычно объявляют как CountedCompleter<Void>, и в качестве значения результата они всегда возвращают null. В других случаях следует переопределить метод getRawResult(), чтобы предоставить результат из join(), invoke() и связанных методов. Как правило, этот метод должен возвращать значение поля (или результат функции от одного или нескольких полей) объекта CountedCompleter, в котором хранится результат после завершения. Метод setRawResult(T) по умолчанию не играет роли в CountedCompleter. Можно, хотя это редко бывает целесообразно, переопределить этот метод для поддержки других объектов или полей, хранящих данные результата.
CountedCompleter, у которого самого нет завершающего объекта (то есть для которого getCompleter() возвращает null), можно использовать как обычный ForkJoinTask с дополнительной функциональностью. Однако любой завершающий объект, у которого, в свою очередь, есть другой завершающий объект, служит только внутренним вспомогательным элементом для других вычислений, поэтому состояние его собственной задачи (отражаемое такими методами, как ForkJoinTask.isDone()) произвольно; оно меняется только при явных вызовах complete(T), ForkJoinTask.cancel(boolean), ForkJoinTask.completeExceptionally(Throwable) или при исключительном завершении метода compute. При любом исключительном завершении исключение может быть передано завершающему объекту задачи (и далее по цепочке), если такой объект существует и еще не завершился иным образом. Аналогично, отмена внутреннего CountedCompleter влияет только на этот завершающий объект и поэтому обычно бесполезна.
Примеры использования.
Параллельная рекурсивная декомпозиция. CountedCompleter можно организовать в деревья, подобные тем, которые часто используются с RecursiveAction, хотя способы их построения обычно различаются. Здесь завершающим объектом каждой задачи является ее родитель в дереве вычислений. Несмотря на то, что для них требуется немного больше учета, CountedCompleter могут быть предпочтительнее при применении потенциально длительной операции (которую нельзя дополнительно разбить) к каждому элементу массива или коллекции; особенно если для некоторых элементов выполнение операции занимает значительно больше времени, чем для других, из-за естественных различий (например, ввода-вывода) или побочных факторов, таких как сборка мусора. Поскольку CountedCompleter предоставляют собственные продолжения, другим задачам не нужно блокироваться в ожидании их выполнения.
Например, ниже приведена начальная версия вспомогательного метода, который использует рекурсивную декомпозицию с делением пополам, чтобы разбить работу на отдельные части (конечные задачи). Даже если работа разделена на отдельные вызовы, методы на основе деревьев обычно предпочтительнее непосредственного порождения конечных задач, поскольку они сокращают обмен данными между потоками и улучшают балансировку нагрузки. В рекурсивном случае вторая из каждой пары завершающихся подзадач запускает завершение родителя (поскольку объединение результатов не выполняется, реализация метода onCompletion по умолчанию, ничего не делающая, не переопределяется). Вспомогательный метод создает корневую задачу и вызывает ее (здесь неявно используется ForkJoinPool.commonPool()). Просто и надежно (но не оптимально) всегда устанавливать счетчик ожидающих действий в число дочерних задач и вызывать
tryComplete() непосредственно перед возвратом.
public static <E> void forEach(E[] array, Consumer<E> action) {
class Task extends CountedCompleter<Void> {
final int lo, hi;
Task(Task parent, int lo, int hi) {
super(parent); this.lo = lo; this.hi = hi;
}
public void compute() {
if (hi - lo >= 2) {
int mid = (lo + hi) >>> 1;
// must set pending count before fork
setPendingCount(2);
new Task(this, mid, hi).fork(); // right child
new Task(this, lo, mid).fork(); // left child
}
else if (hi > lo)
action.accept(array[lo]);
tryComplete();
}
}
new Task(null, 0, array.length).invoke();
} Эту схему можно улучшить, заметив, что в рекурсивном случае после порождения правой задачи самой задаче больше нечего делать, поэтому перед возвратом она может напрямую вызвать левую задачу. (Это аналог устранения хвостовой рекурсии.) Кроме того, когда последнее действие задачи — породить или вызвать подзадачу («хвостовой вызов»), вызов
tryComplete() можно оптимизировать, но тогда счетчик ожидающих действий будет иметь значение на единицу меньше ожидаемого. public void compute() {
if (hi - lo >= 2) {
int mid = (lo + hi) >>> 1;
setPendingCount(1); // looks off by one, but correct!
new Task(this, mid, hi).fork(); // right child
new Task(this, lo, mid).compute(); // direct invoke
} else {
if (hi > lo)
action.accept(array[lo]);
tryComplete();
}
} В качестве дополнительной оптимизации заметим, что левая задача вообще не обязательна. Вместо создания новой задачи можно продолжить использовать исходную и увеличивать счетчик ожидающих действий для каждого порождения задачи. Кроме того, поскольку ни одна задача в этом дереве не реализует метод onCompletion(CountedCompleter), tryComplete можно заменить на propagateCompletion(). public void compute() {
int n = hi - lo;
for (; n >= 2; n /= 2) {
addToPendingCount(1);
new Task(this, lo + n/2, lo + n).fork();
}
if (n > 0)
action.accept(array[lo]);
propagateCompletion();
} Если счетчики ожидающих действий можно вычислить заранее, их можно задать в конструкторе: public static <E> void forEach(E[] array, Consumer<E> action) {
class Task extends CountedCompleter<Void> {
final int lo, hi;
Task(Task parent, int lo, int hi) {
super(parent, 31 - Integer.numberOfLeadingZeros(hi - lo));
this.lo = lo; this.hi = hi;
}
public void compute() {
for (int n = hi - lo; n >= 2; n /= 2)
new Task(this, lo + n/2, lo + n).fork();
action.accept(array[lo]);
propagateCompletion();
}
}
if (array.length > 0)
new Task(null, 0, array.length).invoke();
} К дополнительным оптимизациям таких классов могут относиться создание специализированных классов для конечных шагов, разбиение, например, на четыре части вместо двух за итерацию и использование адаптивного порога вместо постоянного деления до отдельных элементов. Поиск. Дерево CountedCompleter может выполнять поиск значения или свойства в разных частях структуры данных и сообщать результат в AtomicReference, как только результат найден. Остальные задачи могут проверять этот результат, чтобы избежать ненужной работы. (Можно также отменить другие задачи, но обычно проще и эффективнее позволить им обнаружить, что результат установлен, и пропустить дальнейшую обработку.) Снова покажем это на примере массива с полным разбиением (на практике конечные задачи почти всегда обрабатывают более одного элемента):
class Searcher<E> extends CountedCompleter<E> {
final E[] array; final AtomicReference<E> result; final int lo, hi;
Searcher(CountedCompleter<?> p, E[] array, AtomicReference<E> result, int lo, int hi) {
super(p);
this.array = array; this.result = result; this.lo = lo; this.hi = hi;
}
public E getRawResult() { return result.get(); }
public void compute() { // similar to ForEach version 3
int l = lo, h = hi;
while (result.get() == null && h >= l) {
if (h - l >= 2) {
int mid = (l + h) >>> 1;
addToPendingCount(1);
new Searcher(this, array, result, mid, h).fork();
h = mid;
}
else {
E x = array[l];
if (matches(x) && result.compareAndSet(null, x))
quietlyCompleteRoot(); // root task is now joinable
break;
}
}
tryComplete(); // normally complete whether or not found
}
boolean matches(E e) { ... } // return true if found
public static <E> E search(E[] array) {
return new Searcher<E>(null, array, new AtomicReference<E>(), 0, array.length).invoke();
}
} В этом примере, а также в других случаях, когда задачи не имеют иных побочных эффектов, кроме как compareAndSet общий результат, завершающий безусловный вызов tryComplete можно сделать условным (if (result.get() == null) tryComplete();), поскольку после завершения корневой задачи для управления завершением больше не требуется дополнительный учет. Регистрация подзадач. Задачам CountedCompleter, объединяющим результаты нескольких подзадач, обычно требуется доступ к этим результатам в методе onCompletion(CountedCompleter). Как показано в следующем классе (реализующем упрощенную разновидность map-reduce, где отображения и редукции имеют тип E), один из способов сделать это в схемах «разделяй и властвуй» — поручить каждой подзадаче сохранять ссылку на соседнюю задачу, чтобы к ней можно было обратиться в методе onCompletion. Этот прием подходит для редукций, в которых порядок объединения левого и правого результатов не имеет значения; для упорядоченных редукций необходимо явно обозначать левую и правую стороны. Могут также применяться варианты других упрощений, рассмотренных в предыдущих примерах.
class MyMapper<E> { E apply(E v) { ... } }
class MyReducer<E> { E apply(E x, E y) { ... } }
class MapReducer<E> extends CountedCompleter<E> {
final E[] array; final MyMapper<E> mapper;
final MyReducer<E> reducer; final int lo, hi;
MapReducer<E> sibling;
E result;
MapReducer(CountedCompleter<?> p, E[] array, MyMapper<E> mapper,
MyReducer<E> reducer, int lo, int hi) {
super(p);
this.array = array; this.mapper = mapper;
this.reducer = reducer; this.lo = lo; this.hi = hi;
}
public void compute() {
if (hi - lo >= 2) {
int mid = (lo + hi) >>> 1;
MapReducer<E> left = new MapReducer(this, array, mapper, reducer, lo, mid);
MapReducer<E> right = new MapReducer(this, array, mapper, reducer, mid, hi);
left.sibling = right;
right.sibling = left;
setPendingCount(1); // only right is pending
right.fork();
left.compute(); // directly execute left
}
else {
if (hi > lo)
result = mapper.apply(array[lo]);
tryComplete();
}
}
public void onCompletion(CountedCompleter<?> caller) {
if (caller != this) {
MapReducer<E> child = (MapReducer<E>)caller;
MapReducer<E> sib = child.sibling;
if (sib == null || sib.result == null)
result = child.result;
else
result = reducer.apply(child.result, sib.result);
}
}
public E getRawResult() { return result; }
public static <E> E mapReduce(E[] array, MyMapper<E> mapper, MyReducer<E> reducer) {
return new MapReducer<E>(null, array, mapper, reducer,
0, array.length).invoke();
}
} Здесь метод onCompletion имеет форму, типичную для многих схем завершения, объединяющих результаты. Этот метод обратного вызова вызывается один раз для каждой задачи в одном из двух случаев, когда счетчик ожидающих действий равен нулю или становится равен нулю: (1) самой задачей, если ее счетчик ожидающих действий равен нулю при вызове
tryComplete, или (2) любой из ее подзадач, когда они завершаются и уменьшают счетчик ожидающих действий до нуля. Аргумент caller позволяет различить эти случаи. Чаще всего, если вызывающий объект — this, никаких действий не требуется. В противном случае аргумент вызывающего объекта можно использовать (обычно с помощью приведения типа), чтобы передать значение (и/или ссылки на другие значения) для объединения. При правильном использовании счетчиков ожидающих действий действия внутри onCompletion выполняются один раз при завершении задачи и ее подзадач. Для обеспечения потокобезопасного доступа к полям этой задачи или других завершенных задач в рамках этого метода дополнительная синхронизация не требуется. Обходы завершения. Если использование onCompletion для обработки завершений неприменимо или неудобно, можно использовать методы firstComplete() и nextComplete() для создания пользовательских обходов. Например, чтобы определить MapReducer, который порождает только задачи для правых частей, как в третьем примере ForEach, завершения должны совместно выполнять редукцию по ссылкам на незавершенные подзадачи, что можно сделать следующим образом:
class MapReducer<E> extends CountedCompleter<E> { // version 2
final E[] array; final MyMapper<E> mapper;
final MyReducer<E> reducer; final int lo, hi;
MapReducer<E> forks, next; // record subtask forks in list
E result;
MapReducer(CountedCompleter<?> p, E[] array, MyMapper<E> mapper,
MyReducer<E> reducer, int lo, int hi, MapReducer<E> next) {
super(p);
this.array = array; this.mapper = mapper;
this.reducer = reducer; this.lo = lo; this.hi = hi;
this.next = next;
}
public void compute() {
int l = lo, h = hi;
while (h - l >= 2) {
int mid = (l + h) >>> 1;
addToPendingCount(1);
(forks = new MapReducer(this, array, mapper, reducer, mid, h, forks)).fork();
h = mid;
}
if (h > l)
result = mapper.apply(array[l]);
// process completions by reducing along and advancing subtask links
for (CountedCompleter<?> c = firstComplete(); c != null; c = c.nextComplete()) {
for (MapReducer t = (MapReducer)c, s = t.forks; s != null; s = t.forks = s.next)
t.result = reducer.apply(t.result, s.result);
}
}
public E getRawResult() { return result; }
public static <E> E mapReduce(E[] array, MyMapper<E> mapper, MyReducer<E> reducer) {
return new MapReducer<E>(null, array, mapper, reducer,
0, array.length, null).invoke();
}
} Триггеры. Некоторые CountedCompleter никогда не порождаются сами, а служат связующими элементами в других схемах; в том числе в тех, где завершение одной или нескольких асинхронных задач запускает другую асинхронную задачу. Например:
class HeaderBuilder extends CountedCompleter<...> { ... }
class BodyBuilder extends CountedCompleter<...> { ... }
class PacketSender extends CountedCompleter<...> {
PacketSender(...) { super(null, 1); ... } // trigger on second completion
public void compute() { } // never called
public void onCompletion(CountedCompleter<?> caller) { sendPacket(); }
}
// sample use:
PacketSender p = new PacketSender();
new HeaderBuilder(p, ...).fork();
new BodyBuilder(p, ...).fork();
- С версии:
- 1.8
- См. также:
Краткое описание вложенных классов
Вложенные классы/интерфейсы, объявленные в интерфейсе Future
Future.State | Модификатор и тип | Интерфейс | Описание |
|---|---|---|
static enum |
Future.State |
Представляет состояние вычисления. |
Краткое описание конструкторов
| Модификатор | Конструктор | Описание |
|---|---|---|
protected |
Создает новый CountedCompleter без завершающей задачи и с начальным счетчиком ожидающих задач, равным нулю. |
|
protected |
Создает новый CountedCompleter с указанной завершающей задачей и начальным счетчиком ожидающих задач, равным нулю. |
|
protected |
Создает новый CountedCompleter с указанной завершающей задачей и начальным счетчиком ожидающих задач. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
final void |
addToPendingCount |
Атомарно добавляет указанное значение к счетчику ожидающих задач. |
final boolean |
compareAndSetPendingCount |
Атомарно устанавливает счетчик ожидающих задач в указанное значение, только если в данный момент он содержит ожидаемое значение. |
void |
complete |
Независимо от счетчика ожидающих задач вызывает onCompletion(CountedCompleter), помечает эту задачу как завершенную и дополнительно вызывает tryComplete() для завершающей задачи этой задачи, если она существует. |
abstract void |
compute() |
Основное вычисление, выполняемое этой задачей. |
final int |
decrementPendingCountUnlessZero() |
Если счетчик ожидающих задач не равен нулю, атомарно уменьшает его. |
protected final boolean |
exec() |
Реализует соглашения о выполнении для CountedCompleter. |
final CountedCompleter |
firstComplete() |
Если счетчик ожидающих задач этой задачи равен нулю, возвращает эту задачу; в противном случае уменьшает ее счетчик ожидающих задач и возвращает null. |
final CountedCompleter |
getCompleter() |
Возвращает завершающую задачу, заданную в конструкторе этой задачи, или null, если ее нет. |
final int |
getPendingCount() |
Возвращает текущее значение счетчика ожидающих задач. |
T |
getRawResult() |
Возвращает результат вычисления. |
final CountedCompleter |
getRoot() |
Возвращает корень текущего вычисления: эту задачу, если у нее нет завершающей задачи, иначе корень ее завершающей задачи. |
final void |
helpComplete |
Если эта задача не завершена, пытается обработать не более указанного количества других необработанных задач, для которых эта задача находится на пути завершения, если известно о наличии таких задач. |
final CountedCompleter |
nextComplete() |
Если у этой задачи нет завершающей задачи, вызывает ForkJoinTask.quietlyComplete() и возвращает null. |
void |
onCompletion |
Выполняет действие при вызове метода tryComplete() с нулевым счетчиком ожидающих задач или при вызове безусловного метода complete(T). |
boolean |
onExceptionalCompletion |
Выполняет действие при вызове метода ForkJoinTask.completeExceptionally(Throwable) или при возникновении исключения в методе compute(), если эта задача еще не была завершена обычным образом. |
final void |
propagateCompletion() |
Эквивалентен tryComplete(), но не вызывает onCompletion(CountedCompleter) на пути завершения: если счетчик ожидающих задач не равен нулю, уменьшает его; в противном случае аналогичным образом пытается завершить завершающую задачу этой задачи, если она существует, а если нет — помечает эту задачу как завершенную. |
final void |
quietlyCompleteRoot() |
Эквивалентен getRoot().quietlyComplete(). |
final void |
setPendingCount |
Устанавливает счетчик ожидающих задач в указанное значение. |
protected void |
setRawResult |
Метод, который CountedCompleter с результатом может использовать для поддержки данных результата. |
final void |
tryComplete() |
Если счетчик ожидающих задач не равен нулю, уменьшает его; в противном случае вызывает onCompletion(CountedCompleter), а затем аналогичным образом пытается завершить завершающую задачу этой задачи, если она существует, а если нет — помечает эту задачу как завершенную. |
Методы, объявленные в классе ForkJoinTask
adapt, adapt, adapt, adaptInterruptible, adaptInterruptible, adaptInterruptible, cancel, compareAndSetForkJoinTaskTag, completeExceptionally, exceptionNow, fork, get, get, getException, getForkJoinTaskTag, getPool, getQueuedTaskCount, getSurplusQueuedTaskCount, helpQuiesce, inForkJoinPool, invoke, invokeAll, invokeAll, invokeAll, isCancelled, isCompletedAbnormally, isCompletedNormally, isDone, join, peekNextLocalTask, pollNextLocalTask, pollSubmission, pollTask, quietlyComplete, quietlyInvoke, quietlyJoin, quietlyJoin, quietlyJoinUninterruptibly, reinitialize, resultNow, setForkJoinTaskTag, state, tryUnfork | Модификатор и тип | Метод | Описание |
|---|---|---|
static ForkJoinTask |
adapt |
Возвращает новый ForkJoinTask, который выполняет метод run указанного Runnable в качестве действия и возвращает null при вызове ForkJoinTask.join(). |
static <T> ForkJoinTask |
adapt |
Возвращает новый ForkJoinTask, который выполняет метод run указанного Runnable в качестве действия и возвращает указанный результат при вызове ForkJoinTask.join(). |
static <T> ForkJoinTask |
adapt |
Возвращает новый ForkJoinTask, который выполняет метод call указанного Callable в качестве действия и возвращает его результат при вызове ForkJoinTask.join(), преобразуя любые возникшие проверяемые исключения в RuntimeException. |
static ForkJoinTask |
adaptInterruptible |
Возвращает новый ForkJoinTask, который выполняет метод
run указанного Runnable в качестве действия и возвращает null при вызове ForkJoinTask.join(), преобразуя любые возникшие проверяемые исключения в RuntimeException. |
static <T> ForkJoinTask |
adaptInterruptible |
Возвращает новый ForkJoinTask, который выполняет метод run указанного Runnable в качестве действия и возвращает указанный результат при вызове ForkJoinTask.join(), преобразуя любые возникшие проверяемые исключения в RuntimeException. |
static <T> ForkJoinTask |
adaptInterruptible |
Возвращает новый ForkJoinTask, который выполняет метод call указанного Callable в качестве действия и возвращает его результат при вызове ForkJoinTask.join(), преобразуя любые возникшие проверяемые исключения в RuntimeException. |
boolean |
cancel |
Пытается отменить выполнение этой задачи. |
final boolean |
compareAndSetForkJoinTaskTag |
Атомарно устанавливает значение тега этой задачи при выполнении условия. |
void |
completeExceptionally |
Завершает эту задачу аварийно и, если она еще не прервана или не отменена, приводит к тому, что при join и связанных операциях она выбрасывает указанное исключение. |
Throwable |
exceptionNow() |
Возвращает исключение, выброшенное задачей, не дожидаясь ее завершения. |
final ForkJoinTask |
fork() |
Организует асинхронное выполнение этой задачи в пуле, в котором выполняется текущая задача, если это применимо, или с использованием ForkJoinPool.commonPool(), если текущий поток ForkJoinTask.inForkJoinPool(). |
final T |
get() |
При необходимости ожидает завершения вычисления, а затем извлекает его результат. |
final T |
get |
При необходимости ожидает завершения вычисления не более указанного времени, а затем извлекает его результат, если он доступен. |
final Throwable |
getException() |
Возвращает исключение, выброшенное базовым вычислением, или CancellationException, если задача отменена, либо null, если исключения нет или метод еще не завершился. |
final short |
getForkJoinTaskTag() |
Возвращает тег этой задачи. |
static ForkJoinPool |
getPool() |
Возвращает пул, в котором выполняется текущий поток, или null, если текущий поток выполняется вне какого-либо ForkJoinPool. |
static int |
getQueuedTaskCount() |
Возвращает приблизительное количество задач, созданных текущим рабочим потоком, но еще не выполненных. |
static int |
getSurplusQueuedTaskCount() |
Возвращает приблизительную разницу между количеством задач в локальной очереди текущего рабочего потока и количеством других рабочих потоков, которые могут их перехватить, либо ноль, если этот поток не работает в ForkJoinPool. |
static void |
helpQuiesce() |
При необходимости выполняет задачи до тех пор, пока пул, в котором выполняется текущая задача, не перейдет в состояние покоя. |
static boolean |
inForkJoinPool() |
Возвращает true, если текущий поток является ForkJoinWorkerThread, выполняющим вычисление ForkJoinPool. |
final T |
invoke() |
Начинает выполнение этой задачи, при необходимости ожидает ее завершения и возвращает результат либо выбрасывает (непроверяемое) исключение RuntimeException или Error, если такое исключение возникло при базовом вычислении. |
static <T extends ForkJoinTask<?>> |
invokeAll |
Разветвляет все задачи в указанной коллекции и возвращает управление, когда для каждой задачи выполняется условие isDone или возникает (непроверяемое) исключение, которое в этом случае повторно выбрасывается. |
static void |
invokeAll |
Разветвляет указанные задачи и возвращает управление, когда для каждой задачи выполняется условие isDone или возникает (непроверяемое) исключение, которое в этом случае повторно выбрасывается. |
static void |
invokeAll |
Разветвляет указанные задачи и возвращает управление, когда для каждой задачи выполняется условие isDone или возникает (непроверяемое) исключение, которое в этом случае повторно выбрасывается. |
final boolean |
isCancelled() |
Возвращает true, если эта задача была отменена до ее обычного завершения. |
final boolean |
isCompletedAbnormally() |
Возвращает true, если эта задача выбросила исключение или была отменена. |
final boolean |
isCompletedNormally() |
Возвращает true, если эта задача завершилась без выбрасывания исключения и не была отменена. |
final boolean |
isDone() |
Возвращает true, если эта задача завершилась. |
final T |
join() |
Возвращает результат вычисления, когда оно завершено. |
protected static ForkJoinTask |
peekNextLocalTask() |
Возвращает, но не удаляет из очереди и не выполняет задачу, поставленную в очередь текущим потоком, но еще не выполненную, если такая задача доступна немедленно. |
protected static ForkJoinTask |
pollNextLocalTask() |
Удаляет из очереди и возвращает, не выполняя, следующую задачу, поставленную в очередь текущим потоком, но еще не выполненную, если текущий поток работает в ForkJoinPool. |
protected static ForkJoinTask |
pollSubmission() |
Если текущий поток работает в ForkJoinPool, удаляет из очереди и возвращает, не выполняя, задачу, отправленную в пул извне, если такая задача доступна. |
protected static ForkJoinTask |
pollTask() |
Если текущий поток работает в ForkJoinPool, удаляет из очереди и возвращает, не выполняя, следующую задачу, поставленную в очередь текущим потоком, но еще не выполненную, если она доступна; в противном случае возвращает задачу, созданную другим потоком, если такая задача доступна. |
final void |
quietlyComplete() |
Обычно завершает эту задачу, не устанавливая значение. |
final void |
quietlyInvoke() |
Начинает выполнение этой задачи и при необходимости ожидает ее завершения, не возвращая результат и не выбрасывая исключение. |
final void |
quietlyJoin() |
Ожидает завершения этой задачи, не возвращая результат и не выбрасывая исключение. |
final boolean |
quietlyJoin |
Пытается дождаться завершения этой задачи; возвращает true, если задача завершилась (возможно, аварийно) до истечения указанного времени ожидания и текущий поток не был прерван. |
final boolean |
quietlyJoinUninterruptibly |
Пытается дождаться завершения этой задачи; возвращает true, если задача завершилась (возможно, аварийно) до истечения указанного времени ожидания. |
void |
reinitialize() |
Сбрасывает внутреннее состояние учета этой задачи, позволяя впоследствии выполнить fork. |
T |
resultNow() |
Возвращает вычисленный результат, не дожидаясь завершения. |
final short |
setForkJoinTaskTag |
Атомарно устанавливает значение тега этой задачи и возвращает его старое значение. |
Future.State |
state() |
Возвращает состояние вычисления. |
boolean |
tryUnfork() |
Пытается удалить эту задачу из очереди выполнения. |
Методы, объявленные в классе Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait | Модификатор и тип | Метод | Описание |
|---|---|---|
protected Object |
clone() |
Создает и возвращает копию этого объекта. |
boolean |
equals |
Указывает, равен ли какой-либо другой объект этому объекту. |
protected void |
finalize() |
Устарело, будет удалено: этот элемент API может быть удален в будущей версии. Финализация устарела и может быть удалена в одном из будущих выпусков. |
final Class |
getClass() |
Возвращает класс времени выполнения этого Object. |
int |
hashCode() |
Возвращает хеш-код этого объекта. |
final void |
notify() |
Пробуждает один поток, ожидающий на мониторе этого объекта. |
final void |
notifyAll() |
Пробуждает все потоки, ожидающие на мониторе этого объекта. |
String |
toString() |
Возвращает строковое представление объекта. |
final void |
wait() |
Заставляет текущий поток ожидать пробуждения, обычно вследствие уведомления или прерывания. |
final void |
wait |
Заставляет текущий поток ожидать пробуждения, обычно вследствие уведомления или прерывания, либо истечения указанного периода реального времени. |
final void |
wait |
Заставляет текущий поток ожидать пробуждения, обычно вследствие уведомления или прерывания, либо истечения указанного периода реального времени. |
Подробное описание конструкторов
CountedCompleter
protected CountedCompleter(CountedCompleter<?> completer, int initialPendingCount)
- Параметры:
-
completer— задача-завершитель этой задачи илиnull, если ее нет -
initialPendingCount— начальное значение счетчика ожидающих
CountedCompleter
protected CountedCompleter(CountedCompleter<?> completer)
- Параметры:
-
completer— задача-завершитель этой задачи илиnull, если ее нет
CountedCompleter
protected CountedCompleter()
Подробное описание методов
compute
public abstract void compute()
onCompletion
public void onCompletion(CountedCompleter<?> caller)
tryComplete(), когда счетчик ожидающих равен нулю, или при вызове безусловного метода complete(T). По умолчанию этот метод ничего не делает. Различить случаи можно, проверив идентичность заданного аргумента caller. Если он не равен
this, то обычно это подзадача, которая может содержать результаты (и/или ссылки на другие результаты) для объединения.- Параметры:
-
caller— задача, вызывающая этот метод (ей может быть сама эта задача)
onExceptionalCompletion
public boolean onExceptionalCompletion(Throwable ex, CountedCompleter<?> caller)
ForkJoinTask.completeExceptionally(Throwable) или при выбрасывании исключения методом compute(), если эта задача еще не завершилась нормально иным способом. При входе в этот метод эта задача ForkJoinTask.isCompletedAbnormally(). Возвращаемое значение метода определяет дальнейшее распространение исключения: если true и у этой задачи есть задача-завершитель, которая еще не завершена, то эта задача-завершитель также завершается с исключением, совпадающим с исключением этой задачи. Реализация этого метода по умолчанию ничего не делает и возвращает true.- Параметры:
-
ex— исключение -
caller— задача, вызывающая этот метод (ей может быть сама эта задача) - Возвращает:
-
true, если это исключение следует распространить на задачу-завершитель этой задачи, если она есть
getCompleter
public final CountedCompleter<?> getCompleter()
null, если ее нет.- Возвращает:
- задачу-завершитель
getPendingCount
public final int getPendingCount()
- Возвращает:
- текущее значение счетчика ожидающих
setPendingCount
public final void setPendingCount(int count)
- Параметры:
-
count— значение счетчика
addToPendingCount
public final void addToPendingCount(int delta)
- Параметры:
-
delta— добавляемое значение
compareAndSetPendingCount
public final boolean compareAndSetPendingCount(int expected, int count)
- Параметры:
-
expected— ожидаемое значение -
count— новое значение - Возвращает:
-
true, если операция выполнена успешно
decrementPendingCountUnlessZero
public final int decrementPendingCountUnlessZero()
- Возвращает:
- начальное значение счетчика ожидающих (до уменьшения), имевшееся при входе в этот метод
getRoot
public final CountedCompleter<?> getRoot()
- Возвращает:
- корневую задачу текущего вычисления
tryComplete
public final void tryComplete()
onCompletion(CountedCompleter), а затем аналогичным образом пытается завершить задачу-завершитель этой задачи, если она есть, иначе помечает эту задачу как завершенную.propagateCompletion
public final void propagateCompletion()
tryComplete(), но не вызывает onCompletion(CountedCompleter) в цепочке завершения: если счетчик ожидающих не равен нулю, уменьшает его на единицу; в противном случае аналогичным образом пытается завершить задачу-завершитель этой задачи, если она есть, иначе помечает эту задачу как завершенную. Этот метод может быть полезен в случаях, когда onCompletion не следует или не требуется вызывать для каждой задачи-завершителя в вычислении.complete
public void complete(T rawResult)
onCompletion(CountedCompleter), помечает эту задачу как завершенную и дополнительно вызывает tryComplete() для задачи-завершителя этой задачи, если она есть. Заданный rawResult используется как аргумент метода setRawResult(T) перед вызовом onCompletion(CountedCompleter) или пометкой этой задачи как завершенной; его значение имеет смысл только для классов, переопределяющих setRawResult. Этот метод не изменяет счетчик ожидающих. Этот метод может быть полезен, когда требуется принудительно завершить задачу сразу после получения любого одного результата подзадачи (а не всех результатов). Однако в распространенном (и рекомендуемом) случае, когда
setRawResult не переопределен, такого эффекта проще добиться с помощью quietlyCompleteRoot().
- Переопределяет:
-
completeв классеForkJoinTask<T> - Параметры:
-
rawResult— необработанный результат
firstComplete
public final CountedCompleter<?> firstComplete()
null. Этот метод предназначен для использования вместе с nextComplete() в циклах обхода завершения.- Возвращает:
- эту задачу, если счетчик ожидающих был равен нулю, иначе
null
nextComplete
public final CountedCompleter<?> nextComplete()
ForkJoinTask.quietlyComplete() и возвращает null. Если счетчик ожидающих задачи-завершителя не равен нулю, уменьшает этот счетчик на единицу и возвращает null. В противном случае возвращает задачу-завершитель. Этот метод можно использовать в цикле обхода завершения для однородных иерархий задач: for (CountedCompleter<?> c = firstComplete();
c != null;
c = c.nextComplete()) {
// ... process c ...
}
- Возвращает:
- задачу-завершитель или
null, если ее нет
quietlyCompleteRoot
public final void quietlyCompleteRoot()
getRoot().quietlyComplete().helpComplete
public final void helpComplete(int maxTasks)
- Параметры:
-
maxTasks— максимальное число задач для обработки. Если значение меньше или равно нулю, задачи не обрабатываются.
exec
protected final boolean exec()
- Определен в:
-
execв классеForkJoinTask<T> - Возвращает:
-
true, если известно, что эта задача завершилась нормально
getRawResult
public T getRawResult()
null, что подходит для действий Void, но в остальных случаях этот метод следует переопределить — почти всегда так, чтобы он возвращал поле или значение функции от поля, в котором хранится результат после завершения.- Определен в:
-
getRawResultв классеForkJoinTask<T> - Возвращает:
- результат вычисления
setRawResult
protected void setRawResult(T t)
- Определен в:
-
setRawResultв классеForkJoinTask<T> - Параметры:
-
t— значение
© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.