Класс 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
См. также:
Сериализованная форма

Конструкторы

КонструкторОписание
RecursiveAction()

Методы

Модификатор и типМетодОписание
protected abstract voidcompute()

Основное вычисление, выполняемое этой задачей.

protected booleanexec()

Реализует соглашения об выполнении для RecursiveActions.

VoidgetRawResult()

Всегда возвращает null.

protected voidsetRawResult​(Void mustBeNull)

Требует значение завершения null.

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

adapt, adapt, adapt, cancel, compareAndSetForkJoinTaskTag, complete, completeExceptionally, fork, get, get, getException, getForkJoinTaskTag, getPool, getQueuedTaskCount, getSurplusQueuedTaskCount, helpQuiesce, inForkJoinPool, invoke, invokeAll, invokeAll, invokeAll, isCompletedAbnormally, isCompletedNormally, join, peekNextLocalTask, pollNextLocalTask, pollSubmission, pollTask, quietlyComplete, quietlyInvoke, quietlyJoin, reinitialize, setForkJoinTaskTag, tryUnfork

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

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Методы, объявленные в интерфейсе java.util.concurrent.Future

isCancelled, isDone

Конструкторы

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()

Реализует соглашения об выполнении для RecursiveActions.

Определено в:
exec в классе ForkJoinTask<Void>
Возвращает:
true если эта задача завершена обычно

© 1993, 2020, 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.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/RecursiveAction.html

Spec-Zone .ru
спецификации, руководства, описания, API