public abstract class RecursiveAction
extends ForkJoinTask<Void>
java.lang.Object | ||
↳ | java.util.concurrent.ForkJoinTask<java.lang.Void> | |
↳ | java.util.concurrent.RecursiveAction |
递归无结果ForkJoinTask
。 这个类建立约定来参数化无结果行为Void
ForkJoinTask
s。 因为null
的类型是唯一有效的值Void
,如方法join
总是返回null
完成时。
样本使用。 这是一个简单但完整的ForkJoin排序, long[]
给定的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++];
}
}
You could then sort
anArray
by creating
new SortTask(anArray)
and invoking it in a ForkJoinPool. As a more concrete simple example, the following task increments each element of an array:
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不需要完全递归,只要它们保持基本的分而治之的方法。 这里是一个类,它将双数组中的每个元素的平方相加,只通过将重复分割的右侧分为两部分,并用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;
}
}
Public constructors |
|
---|---|
RecursiveAction() |
Public methods |
|
---|---|
final Void |
getRawResult() 总是返回 |
Protected methods |
|
---|---|
abstract void |
compute() 此任务执行的主要计算。 |
final boolean |
exec() 为RecursiveActions实现执行约定。 |
final void |
setRawResult(Void mustBeNull) 需要空值完成值。 |
Inherited methods |
|
---|---|
From class java.util.concurrent.ForkJoinTask
|
|
From class java.lang.Object
|
|
From interface java.util.concurrent.Future
|
boolean exec ()
为RecursiveActions实现执行约定。
Returns | |
---|---|
boolean |
true if this task is known to have completed normally |
void setRawResult (Void mustBeNull)
需要空值完成值。
Parameters | |
---|---|
mustBeNull |
Void : the value |