jsr166z.forkjoin
Class LinkedAsyncAction

java.lang.Object
  extended by jsr166z.forkjoin.ForkJoinTask<java.lang.Void>
      extended by jsr166z.forkjoin.LinkedAsyncAction

public abstract class LinkedAsyncAction
extends ForkJoinTask<java.lang.Void>

Resultless ForkJoinTasks with explicit completions, that may be linked in parent-child relationships. Unlike other kinds of tasks, LinkedAsyncActions do not intrinisically complete upon exit from their compute methods, but instead require explicit invocation of their finish methods and completion of subtasks.

Upon construction, an LinkedAsyncAction may register as a subtask of a given parent task. In this case, completion of this task will propagate to its parent. If the parent's pending subtask completion count becomes zero, it too will finish. LinkedAsyncActions rarely use methods join or invoke but instead propagate completion to parents implicitly via finish. While typical, it is not necessary for each task to finish itself. For example, it is possible to treat one subtask as a continuation of the current task by not registering it on construction. In this case, a finish of the subtask will trigger finish of the parent without the parent explicitly doing so.

In addition to supporting these different computation styles compared to Recursive tasks, LinkedAsyncActions may have smaller stack space footprints while executing, but may have greater per-task overhead.

Sample Usage. Here is a sketch of an LinkedAsyncAction that visits all of the nodes of a graph. The details of the graph's Node and Edge classes are omitted, but we assume each node contains an AtomicBoolean mark that starts out false. To execute this, you would create a GraphVisitor for the root node with null parent, and invoke in a ForkJoinPool. Upon return, all reachable nodes will have been visited.

 class GraphVisitor extends LinkedAsyncAction {
    final Node node;
    GraphVisitor(GraphVistor parent, Node node) {
      super(parent); this.node = node;
    }
    protected void compute() {
      if (node.mark.compareAndSet(false, true)) {
         for (Edge e : node.edges()) {
            Node dest = e.getDestination();
            if (!dest.mark.get())
               new GraphVisitor(this, dest).fork();
         }
         visit(node);
      }
      finish();
   }
 }
 


Constructor Summary
protected LinkedAsyncAction()
          Creates a new action with no parent.
protected LinkedAsyncAction(LinkedAsyncAction parent)
          Creates a new action with the given parent.
protected LinkedAsyncAction(LinkedAsyncAction parent, boolean register)
          Creates a new action with the given parent, optionally registering with the parent.
protected LinkedAsyncAction(LinkedAsyncAction parent, boolean register, int pending)
          Creates a new action with the given parent, optionally registering with the parent, and setting the pending join count to the given value.
 
Method Summary
protected abstract  void compute()
          The asynchronous part of the 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.
 void finishExceptionally(java.lang.Throwable ex)
          Completes this task abnormally.
 LinkedAsyncAction getParent()
          Returns this task's parent, or null if none.
 int getPendingSubtaskCount()
          Returns the number of subtasks that have not yet completed.
 java.lang.Void invoke()
          Equivalent in effect to the sequence fork(); join(); but may be more efficient.
protected  void onCompletion()
          Overridable callback action triggered by finish.
protected  boolean onException()
          Overridable callback action triggered by finishExceptionally.
 java.lang.Void rawResult()
          Always returns null.
 void reinitialize()
          Resets the internal bookkeeping state of this task, maintaining the current parent but clearing pending joins.
 void reinitialize(int pending)
          Resets the internal bookkeeping state of this task, maintaining the current parent and setting pending joins to the given value.
 void reinitialize(LinkedAsyncAction parent, boolean register)
          Reinitialize with the given parent, optionally registering.
 void reinitialize(LinkedAsyncAction parent, boolean register, int pending)
          Reinitialize with the given parent, optionally registering and setting pending join count.
 
Methods inherited from class jsr166z.forkjoin.ForkJoinTask
cancel, fork, getException, isCancelled, isDone, isStolen, join, quietlyJoin
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

LinkedAsyncAction

protected LinkedAsyncAction()
Creates a new action with no parent. (You can add a parent later (but before forking) via reinitialize).


LinkedAsyncAction

protected LinkedAsyncAction(LinkedAsyncAction parent)
Creates a new action with the given parent. If the parent is non-null, this tasks registers with the parent, in which case, the parent task cannot complete until this task completes.

Parameters:
parent - the parent task, or null if none

LinkedAsyncAction

protected LinkedAsyncAction(LinkedAsyncAction parent,
                            boolean register)
Creates a new action with the given parent, optionally registering with the parent. If the parent is non-null and register is true, this tasks registers with the parent, in which case, the parent task cannot complete until this task completes.

Parameters:
parent - the parent task, or null if none
register - true if parent must wait for this task to complete before it completes

LinkedAsyncAction

protected LinkedAsyncAction(LinkedAsyncAction parent,
                            boolean register,
                            int pending)
Creates a new action with the given parent, optionally registering with the parent, and setting the pending join count to the given value. If the parent is non-null and register is true, this tasks registers with the parent, in which case, the parent task cannot complete until this task completes. Setting the pending join count requires care -- it is correct only if child tasks do not themselves register.

Parameters:
parent - the parent task, or null if none
register - true if parent must wait for this task to complete before it completes
pending - the pending join count
Method Detail

compute

protected abstract void compute()
The asynchronous part of the computation performed by this task. While you must define this method, you should not in general call it directly (although you can invoke immediately via exec.) If this method throws a Throwable, finishExceptionally is immediately invoked.


onCompletion

protected void onCompletion()
Overridable callback action triggered by finish. Upon invocation, all subtasks have completed. After return, this task isDone and is joinable by other tasks. The default version of this method does nothing. But it may may be overridden in subclasses to perform some action when this task is about to complete.


onException

protected boolean onException()
Overridable callback action triggered by finishExceptionally. Upon invocation, this task has aborted due to an exception (accessible via getException). If this method returns true, the exception propagates to the current task's parent. Otherwise, normal completion is propagated. The default version of this method does nothing and returns true.

Returns:
true if this task's exception should be propagated to this tasks parent.

finish

public final void finish()
Equivalent to finish(null).


finish

public final void finish(java.lang.Void result)
Completes this task. If the pending subtask completion count is zero, invokes onCompletion, then causes this task to be joinable (isDone becomes true), and then recursively applies to this tasks's parent, if it exists. If an exception is encountered in any onCompletion invocation, that task and its ancestors finishExceptionally.

Specified by:
finish in class ForkJoinTask<java.lang.Void>
Parameters:
result - must be null.

finishExceptionally

public final void finishExceptionally(java.lang.Throwable ex)
Completes this task abnormally. Unless this task already cancelled or aborted, upon invocation, this method invokes onException, and then, depending on its return value, finishes parent (if one exists) exceptionally or normally. To avoid unbounded exception loops, this method aborts if an exception is encountered in any onException invocation.

Specified by:
finishExceptionally in class ForkJoinTask<java.lang.Void>
Parameters:
ex - the exception to throw when joining this task
Throws:
java.lang.NullPointerException - if ex is null
java.lang.Throwable - if any invocation of onException does so.

getParent

public final LinkedAsyncAction getParent()
Returns this task's parent, or null if none.

Returns:
this task's parent, or null if none.

getPendingSubtaskCount

public final int getPendingSubtaskCount()
Returns the number of subtasks that have not yet completed.

Returns:
the number of subtasks that have not yet completed.

rawResult

public final java.lang.Void rawResult()
Always returns null.

Specified by:
rawResult in class ForkJoinTask<java.lang.Void>
Returns:
null

reinitialize

public void reinitialize()
Resets the internal bookkeeping state of this task, maintaining the current parent but clearing pending joins.

Overrides:
reinitialize in class ForkJoinTask<java.lang.Void>

reinitialize

public void reinitialize(int pending)
Resets the internal bookkeeping state of this task, maintaining the current parent and setting pending joins to the given value.

Parameters:
pending - the number of pending joins

reinitialize

public void reinitialize(LinkedAsyncAction parent,
                         boolean register)
Reinitialize with the given parent, optionally registering.

Parameters:
parent - the parent task, or null if none
register - true if parent must wait for this task to complete before it completes

reinitialize

public void reinitialize(LinkedAsyncAction parent,
                         boolean register,
                         int pending)
Reinitialize with the given parent, optionally registering and setting pending join count.

Parameters:
parent - the parent task, or null if none
register - true if parent must wait for this task to complete before it completes
pending - the pending join count

invoke

public final java.lang.Void invoke()
Description copied from class: ForkJoinTask
Equivalent in effect to the sequence fork(); join(); but may be more efficient.

Specified by:
invoke in class ForkJoinTask<java.lang.Void>
Returns:
the computed result

exec

public final java.lang.Throwable exec()
Description copied from class: ForkJoinTask
Immediately commences execution of this task by the current worker thread unless already cancelled, returning any exception thrown by its compute method.

Specified by:
exec in class ForkJoinTask<java.lang.Void>
Returns:
exception thrown by compute (or via cancellation), or null if none