Spec-Zone.ru › OpenJDK 17

Класс 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));
     }
   }
 }

Следующий пример иллюстрирует некоторые усовершенствования и методы, которые могут привести к лучшей производительности: RecursiveActions не обязательно должны быть полностью рекурсивными, пока они сохраняют основной подход «разделяй и властвуй». Вот класс, который суммирует квадраты каждого элемента массива 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 void compute()
Основное вычисление, выполняемое этой задачей.
protected final boolean exec()
Реализует соглашения об выполнении для RecursiveActions.
final Void getRawResult()
Всегда возвращает null.
protected final void setRawResult(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, isCancelled, isCompletedAbnormally, isCompletedNormally, isDone, 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

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

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, 2021, 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/17/docs/api/java.base/java/util/concurrent/RecursiveAction.html

Spec-Zone.ru

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