|
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectjsr166z.forkjoin.ForkJoinTask<java.lang.Void>
jsr166z.forkjoin.RecursiveAction
public abstract class RecursiveAction
Recursive resultless ForkJoinTasks. To maintain conformance with other classes in this framework, RecursiveActions are parameterized as Void ForkJoinTasks, and return null as results. But for simplicity and efficiency, the compute method and related methods use void. RecursiveActions normally proceed via parallel divide and conquer; very often using the convenient (and typically more efficient) combined method coInvoke. Here is a sketch of a ForkJoin sort that sorts a given long[] array:
class SortTask extends RecursiveAction { final long[] array; final int lo; final int hi; SortTask(long[] array, int lo, int hi) { this.array = array; this.lo = lo; this.hi = hi; } protected void compute() { if (hi - lo < THRESHOLD) sequentiallySort(array, lo, hi); else { int mid = (lo + hi) >>> 1; coInvoke(new SortTask(array, lo, mid), new SortTask(array, mid+1, hi)); merge(array, lo, hi); } return null; } }You could then sort anArray by creating new SortTask(anArray, 0, anArray.length-1) and invoking it in a ForkJoinPool.
RecursiveActions need not be fully recursive, so long as they maintain the basic divide-and-conquer approach. For example, here is a class that sums the squares of each element of a double array, by subdividing out only the right-hand-sides of repeated divisions by two, and keeping track of them with a chain of next references. It uses a common rule of thumb for granularity settings, corresponding to about eight times as many base tasks as there are threads in the pool.
double sumOfSquares(ForkJoinPool pool, double[] array) { int n = array.length; int seqSize = 1 + n / (8 * pool.getParallelismLevel()); Applyer a = new Applyer(array, 0, n-1, seqSize, null); pool.invoke(a); return a.result; } class Applyer extends RecursiveAction { final double[] array; final int lo, hi, seqSize; int result; Applyer next; // keeps track of right-hand-side tasks Applyer(double[] array, int lo, int hi, int seqSize, Applyer next) { this.array = array; this.lo = lo; this.hi = hi; this.seqSize = seqSize; this.next = next; } protected void compute() { int l = lo; int h = hi; Applyer right = null; while (h - l > seqSize) { // fork right-hand sides int mid = (l + h) >>> 1; right = new Applyer(array, mid+1, h, seqSize, right); right.fork(); h = mid; } double sum = 0; for (int i = l; i <= h; ++i) // perform leftmost base step sum += array[i] * array[i]; while (right != null) { // join right-hand sides right.join(); sum += right.result; right = right.next; } result = sum; } }
Constructor Summary | |
---|---|
RecursiveAction()
|
Method Summary | |
---|---|
static void |
coInvoke(java.util.List<? extends RecursiveAction> tasks)
Forks all tasks in the list, returning when isDone holds for all of them. |
static void |
coInvoke(RecursiveAction[] tasks)
Forks all tasks in the array, returning when isDone holds for all of them. |
static void |
coInvoke(RecursiveAction t1,
RecursiveAction t2)
Forks both tasks and returns when isDone holds for both.. |
protected abstract void |
compute()
The main computation performed by this task. |
java.lang.Throwable |
exec()
Immediately commences execution of this task by the current worker thread unless already cancelled, returning any exception thrown by its compute method. |
void |
finish()
Equivalent to finish(null). |
void |
finish(java.lang.Void result)
Completes this task, and if not already aborted or cancelled, returning the given result upon join and related operations. |
void |
finishExceptionally(java.lang.Throwable ex)
Completes this task abnormally, and if not already aborted or cancelled, causes it to throw the given exception upon join and related operations. |
java.lang.Void |
invoke()
Equivalent in effect to the sequence fork(); join(); but may be more efficient. |
java.lang.Void |
rawResult()
Always returns null. |
Methods inherited from class jsr166z.forkjoin.ForkJoinTask |
---|
cancel, fork, getException, isCancelled, isDone, isStolen, join, quietlyJoin, reinitialize |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Constructor Detail |
---|
public RecursiveAction()
Method Detail |
---|
protected abstract void compute()
public static void coInvoke(RecursiveAction t1, RecursiveAction t2)
java.lang.NullPointerException
- if t1 or t2 are null.public static void coInvoke(RecursiveAction[] tasks)
java.lang.NullPointerException
- if array or any element of array are nullpublic static void coInvoke(java.util.List<? extends RecursiveAction> tasks)
java.lang.NullPointerException
- if list or any element of list are null.public final java.lang.Void rawResult()
rawResult
in class ForkJoinTask<java.lang.Void>
public final java.lang.Void invoke()
ForkJoinTask
invoke
in class ForkJoinTask<java.lang.Void>
public final java.lang.Throwable exec()
ForkJoinTask
exec
in class ForkJoinTask<java.lang.Void>
public final void finish()
public final void finish(java.lang.Void result)
ForkJoinTask
finish
in class ForkJoinTask<java.lang.Void>
result
- the result to returnpublic final void finishExceptionally(java.lang.Throwable ex)
ForkJoinTask
finishExceptionally
in class ForkJoinTask<java.lang.Void>
ex
- the exception to throw. While not necessarily
statically enforced, this must be a RuntimeException or Error.
|
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |