Spec-Zone.ru › OpenJDK 27

Класс RecursiveAction

java.lang.Object
java.util.concurrent.ForkJoinTask<Void>
java.util.concurrent.RecursiveAction
Все реализованные интерфейсы:
Serializable, Future<Void>
public abstract class RecursiveAction extends ForkJoinTask<Void>
Рекурсивная задача без результата ForkJoinTask. Этот класс устанавливает соглашения для параметризации действий без результата в виде Void ForkJoinTaskов. Поскольку null — единственное допустимое значение типа Void, такие методы, как join, всегда возвращают null после завершения.

Примеры использования. Ниже приведён простой, но полный пример сортировки с помощью ForkJoin, которая сортирует заданный массив long[]:

static class SortTask extends RecursiveAction {
  final long[] array; final int lo, hi;
  SortTask(long[] array, int lo, int hi) {
    this.array = array; this.lo = lo; this.hi = hi;
  }
  SortTask(long[] array) { this(array, 0, array.length); }
  protected void compute() {
    if (hi - lo < THRESHOLD)
      sortSequentially(lo, hi);
    else {
      int mid = (lo + hi) >>> 1;
      invokeAll(new SortTask(array, lo, mid),
                new SortTask(array, mid, hi));
      merge(lo, mid, hi);
    }
  }
  // implementation details follow:
  static final int THRESHOLD = 1000;
  void sortSequentially(int lo, int hi) {
    Arrays.sort(array, lo, hi);
  }
  void merge(int lo, int mid, int hi) {
    long[] buf = Arrays.copyOfRange(array, lo, mid);
    for (int i = 0, j = lo, k = mid; i < buf.length; j++)
      array[j] = (k == hi || buf[i] < array[k]) ?
        buf[i++] : array[k++];
  }
}
Затем можно отсортировать anArray, создав new SortTask(anArray) и вызвав его в ForkJoinPool. В качестве более конкретного простого примера следующая задача увеличивает каждый элемент массива:
class IncrementTask extends RecursiveAction {
  final long[] array; final int lo, hi;
  IncrementTask(long[] array, int lo, int hi) {
    this.array = array; this.lo = lo; this.hi = hi;
  }
  protected void compute() {
    if (hi - lo < THRESHOLD) {
      for (int i = lo; i < hi; ++i)
        array[i]++;
    }
    else {
      int mid = (lo + hi) >>> 1;
      invokeAll(new IncrementTask(array, lo, mid),
                new IncrementTask(array, mid, hi));
    }
  }
}

В следующем примере показаны некоторые усовершенствования и идиомы, которые могут повысить производительность: RecursiveAction не обязательно должны быть полностью рекурсивными, если они сохраняют базовый подход «разделяй и властвуй». Ниже приведён класс, который суммирует квадраты каждого элемента массива double, разделяя только правые части последовательных делений пополам и отслеживая их с помощью цепочки ссылок next. В нём используется динамический порог, основанный на методе getSurplusQueuedTaskCount, но потенциальное избыточное разбиение компенсируется непосредственным выполнением конечных действий для незахваченных задач вместо дальнейшего разбиения.

double sumOfSquares(ForkJoinPool pool, double[] array) {
  int n = array.length;
  Applyer a = new Applyer(array, 0, n, null);
  pool.invoke(a);
  return a.result;
}

class Applyer extends RecursiveAction {
  final double[] array;
  final int lo, hi;
  double result;
  Applyer next; // keeps track of right-hand-side tasks
  Applyer(double[] array, int lo, int hi, Applyer next) {
    this.array = array; this.lo = lo; this.hi = hi;
    this.next = next;
  }

  double atLeaf(int l, int h) {
    double sum = 0;
    for (int i = l; i < h; ++i) // perform leftmost base step
      sum += array[i] * array[i];
    return sum;
  }

  protected void compute() {
    int l = lo;
    int h = hi;
    Applyer right = null;
    while (h - l > 1 && getSurplusQueuedTaskCount() <= 3) {
      int mid = (l + h) >>> 1;
      right = new Applyer(array, mid, h, right);
      right.fork();
      h = mid;
    }
    double sum = atLeaf(l, h);
    while (right != null) {
      if (right.tryUnfork()) // directly calculate if not stolen
        sum += right.atLeaf(right.lo, right.hi);
      else {
        right.join();
        sum += right.result;
      }
      right = right.next;
    }
    result = sum;
  }
}
С момента:
1.7
См. также:
  • Сериализованная форма

Краткое описание вложенных классов

Вложенные классы и интерфейсы, объявленные в интерфейсе Future

Future.State
Модификатор и тип Интерфейс Описание
static enum  Future.State
Представляет состояние вычисления.

Краткое описание конструкторов

Конструктор Описание
RecursiveAction()
Конструктор, который вызывается подклассами.

Краткое описание методов

Модификатор и тип Метод Описание
protected abstract void compute()
Основное вычисление, выполняемое этой задачей.
protected final boolean exec()
Реализует соглашения о выполнении для RecursiveAction.
final Void getRawResult()
Всегда возвращает null.
protected final void setRawResult(Void mustBeNull)
Требует значения null для завершения.

Методы, объявленные в классе ForkJoinTask

adapt, adapt, adapt, adaptInterruptible, adaptInterruptible, adaptInterruptible, cancel, compareAndSetForkJoinTaskTag, complete, 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(Runnable runnable)
Возвращает новый ForkJoinTask, который выполняет метод run заданного Runnable в качестве действия и возвращает результат null при вызове ForkJoinTask.join().
static <T> ForkJoinTask<T> adapt(Runnable runnable, T result)
Возвращает новый ForkJoinTask, который выполняет метод run заданного Runnable в качестве действия и возвращает заданный результат при вызове ForkJoinTask.join().
static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable)
Возвращает новый ForkJoinTask, который выполняет метод call заданного Callable в качестве действия и возвращает его результат при вызове ForkJoinTask.join(), преобразуя все возникшие проверяемые исключения в RuntimeException.
static ForkJoinTask<?> adaptInterruptible(Runnable runnable)
Возвращает новый ForkJoinTask, который выполняет метод run заданного Runnable в качестве действия и возвращает null при вызове ForkJoinTask.join(), преобразуя все возникшие проверяемые исключения в RuntimeException.
static <T> ForkJoinTask<T> adaptInterruptible(Runnable runnable, T result)
Возвращает новый ForkJoinTask, который выполняет метод run заданного Runnable в качестве действия и возвращает заданный результат при вызове ForkJoinTask.join(), преобразуя все возникшие проверяемые исключения в RuntimeException.
static <T> ForkJoinTask<T> adaptInterruptible(Callable<? extends T> callable)
Возвращает новый ForkJoinTask, который выполняет метод call заданного Callable в качестве действия и возвращает его результат при вызове ForkJoinTask.join(), преобразуя все возникшие проверяемые исключения в RuntimeException.
boolean cancel(boolean mayInterruptIfRunning)
Пытается отменить выполнение этой задачи.
final boolean compareAndSetForkJoinTaskTag(short expect, short update)
Атомарно и при выполнении условия устанавливает значение тега этой задачи.
void complete(Void value)
Завершает эту задачу и, если она ещё не была прервана или отменена, возвращает заданное значение как результат последующих вызовов join и связанных операций.
void completeExceptionally(Throwable ex)
Завершает эту задачу аварийно и, если она ещё не была прервана или отменена, вызывает указанное исключение при вызове join и связанных операций.
Throwable exceptionNow()
Возвращает исключение, выброшенное задачей, не дожидаясь её завершения.
final ForkJoinTask<Void> fork()
Запускает асинхронное выполнение этой задачи в пуле, в котором выполняется текущая задача, если это применимо, либо в ForkJoinPool.commonPool(), если текущий поток не ForkJoinTask.inForkJoinPool().
final Void get()
При необходимости ожидает завершения вычисления, а затем получает его результат.
final Void get(long timeout, TimeUnit unit)
При необходимости ожидает завершения вычисления не дольше заданного времени, а затем получает его результат, если он доступен.
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 Void invoke()
Начинает выполнение этой задачи, при необходимости ожидает её завершения и возвращает результат либо выбрасывает (непроверяемое) исключение RuntimeException или Error, если оно возникло при базовом вычислении.
static <T extends ForkJoinTask<?>>
Collection<T>
invokeAll(Collection<T> tasks)
Порождает все задачи из указанной коллекции и возвращает управление, когда для каждой задачи выполняется условие isDone либо возникает (непроверяемое) исключение; в последнем случае исключение выбрасывается повторно.
static void invokeAll(ForkJoinTask<?>... tasks)
Порождает заданные задачи и возвращает управление, когда для каждой задачи выполняется условие isDone либо возникает (непроверяемое) исключение; в последнем случае исключение выбрасывается повторно.
static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2)
Порождает заданные задачи и возвращает управление, когда для каждой задачи выполняется условие isDone либо возникает (непроверяемое) исключение; в последнем случае исключение выбрасывается повторно.
final boolean isCancelled()
Возвращает true, если эта задача была отменена до её нормального завершения.
final boolean isCompletedAbnormally()
Возвращает true, если эта задача выбросила исключение или была отменена.
final boolean isCompletedNormally()
Возвращает true, если эта задача завершилась без исключения и не была отменена.
final boolean isDone()
Возвращает true, если эта задача завершилась.
final Void 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(long timeout, TimeUnit unit)
Пытается дождаться завершения этой задачи; возвращает true, если задача завершилась (возможно, аварийно) до истечения заданного времени ожидания и текущий поток не был прерван.
final boolean quietlyJoinUninterruptibly(long timeout, TimeUnit unit)
Пытается дождаться завершения этой задачи; возвращает true, если задача завершилась (возможно, аварийно) до истечения заданного времени ожидания.
void reinitialize()
Сбрасывает внутреннее состояние учёта этой задачи, позволяя выполнить последующий вызов fork.
Void resultNow()
Возвращает вычисленный результат, не дожидаясь завершения.
final short setForkJoinTaskTag(short newValue)
Атомарно устанавливает значение тега этой задачи и возвращает его предыдущее значение.
Future.State state()
Возвращает состояние вычисления.
boolean tryUnfork()
Пытается снять эту задачу с очереди на выполнение.

Методы, объявленные в классе Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Модификатор и тип Метод Описание
protected Object clone()
Создаёт и возвращает копию этого объекта.
boolean equals(Object obj)
Указывает, равен ли какой-либо другой объект этому объекту.
protected void finalize()
Устарело, планируется удаление: этот элемент API может быть удалён в будущей версии.
Финализация устарела и может быть удалена в одном из будущих выпусков.
final Class<?> getClass()
Возвращает класс времени выполнения этого Object.
int hashCode()
Возвращает хеш-код этого объекта.
final void notify()
Пробуждает один поток, ожидающий на мониторе этого объекта.
final void notifyAll()
Пробуждает все потоки, ожидающие на мониторе этого объекта.
String toString()
Возвращает строковое представление объекта.
final void wait()
Заставляет текущий поток ожидать пробуждения, обычно вследствие вызова notify или interrupt.
final void wait(long timeoutMillis)
Заставляет текущий поток ожидать пробуждения, обычно вследствие вызова notify или interrupt, либо истечения заданного промежутка реального времени.
final void wait(long timeoutMillis, int nanos)
Заставляет текущий поток ожидать пробуждения, обычно вследствие вызова notify или interrupt, либо истечения заданного промежутка реального времени.

Подробное описание конструкторов

RecursiveAction

public RecursiveAction()
Конструктор, который вызывается подклассами.

Подробное описание методов

compute

protected abstract void compute()
Основное вычисление, выполняемое этой задачей.

getRawResult

public final Void getRawResult()
Всегда возвращает null.
Определено в:
getRawResult в классе ForkJoinTask<Void>
Возвращает:
null всегда

setRawResult

protected final void setRawResult(Void mustBeNull)
Требует значения null для завершения.
Определено в:
setRawResult в классе ForkJoinTask<Void>
Параметры:
mustBeNull — значение

exec

protected final boolean exec()
Реализует соглашения о выполнении для RecursiveAction.
Определено в:
exec в классе ForkJoinTask<Void>
Возвращает:
true, если известно, что эта задача завершилась в обычном режиме

Сообщить об ошибке или предложить улучшение
Дополнительные справочные материалы по API и документацию для разработчиков см. в разделе Документация Java SE, содержащем более подробные описания для разработчиков, концептуальные обзоры, определения терминов, обходные решения и работающие примеры кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или её аффилированных лиц в США и других странах.
Авторские права © 1993, 2026, Oracle и/или её аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 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.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API