ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/LinkedAsyncAction.java
(Generate patch)

Comparing jsr166/src/test/loops/LinkedAsyncAction.java (file contents):
Revision 1.4 by jsr166, Sat Jan 28 04:40:12 2012 UTC vs.
Revision 1.15 by jsr166, Thu Jan 15 18:42:39 2015 UTC

# Line 1 | Line 1
1   /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at
4 < *
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   */
6  
7   import java.util.*;
# Line 11 | Line 11 | import java.util.concurrent.atomic.*;
11   /**
12   * AsyncActions that may be linked in parent-child relationships.
13   *
14 < * <p> Upon construction, an LinkedAsyncAction may register as a
14 > * <p>Upon construction, a LinkedAsyncAction may register as a
15   * subtask of a given parent task. In this case, completion of this
16   * task will propagate to its parent. If the parent's pending subtask
17   * completion count becomes zero, it too will complete.
18 < * LinkedAsyncActions rarely use methods <tt>join</tt> or
19 < * <tt>invoke</tt> but instead propagate completion to parents
20 < * implicitly via <tt>complete</tt>.  While typical, it is not necessary
21 < * for each task to <tt>complete</tt> itself. For example, it is
18 > * LinkedAsyncActions rarely use methods {@code join} or
19 > * {@code invoke} but instead propagate completion to parents
20 > * implicitly via {@code complete}.  While typical, it is not necessary
21 > * for each task to {@code complete} itself. For example, it is
22   * possible to treat one subtask as a continuation of the current task
23   * by not registering it on construction.  In this case, a
24 < * <tt>complete</tt> of the subtask will trigger <tt>complete</tt> of the
24 > * {@code complete} of the subtask will trigger {@code complete} of the
25   * parent without the parent explicitly doing so.
26   *
27 < * <p> In addition to supporting these different computation styles
27 > * <p>In addition to supporting these different computation styles
28   * compared to Recursive tasks, LinkedAsyncActions may have smaller
29   * stack space footprints while executing, but may have greater
30   * per-task overhead.
31   *
32 < * <p> <b>Sample Usage.</b> Here is a sketch of an LinkedAsyncAction
32 > * <p><b>Sample Usage.</b> Here is a sketch of a LinkedAsyncAction
33   * that visits all of the nodes of a graph. The details of the graph's
34   * Node and Edge classes are omitted, but we assume each node contains
35 < * an <tt>AtomicBoolean</tt> mark that starts out false. To execute
35 > * an {@code AtomicBoolean} mark that starts out false. To execute
36   * this, you would create a GraphVisitor for the root node with null
37 < * parent, and <tt>invoke</tt> in a ForkJoinPool. Upon return, all
37 > * parent, and {@code invoke} in a ForkJoinPool. Upon return, all
38   * reachable nodes will have been visited.
39   *
40   * <pre>
41   * class GraphVisitor extends LinkedAsyncAction {
42 < *    final Node node;
43 < *    GraphVisitor(GraphVistor parent, Node node) {
44 < *      super(parent); this.node = node;
45 < *    }
46 < *    protected void compute() {
47 < *      if (node.mark.compareAndSet(false, true)) {
48 < *         for (Edge e : node.edges()) {
49 < *            Node dest = e.getDestination();
50 < *            if (!dest.mark.get())
51 < *               new GraphVisitor(this, dest).fork();
52 < *         }
53 < *         visit(node);
54 < *      }
55 < *      complete();
42 > *   final Node node;
43 > *   GraphVisitor(GraphVisitor parent, Node node) {
44 > *     super(parent); this.node = node;
45 > *   }
46 > *   protected void compute() {
47 > *     if (node.mark.compareAndSet(false, true)) {
48 > *       for (Edge e : node.edges()) {
49 > *         Node dest = e.getDestination();
50 > *         if (!dest.mark.get())
51 > *           new GraphVisitor(this, dest).fork();
52 > *       }
53 > *       visit(node);
54 > *     }
55 > *     complete();
56   *   }
57   * }
58   * </pre>
59 *
59   */
60   public abstract class LinkedAsyncAction extends ForkJoinTask<Void> {
61  
# Line 70 | Line 69 | public abstract class LinkedAsyncAction
69      static final AtomicIntegerFieldUpdater<LinkedAsyncAction> controlStateUpdater =
70          AtomicIntegerFieldUpdater.newUpdater(LinkedAsyncAction.class, "controlState");
71  
73
72      /**
73       * Parent to notify on completion
74       */
# Line 78 | Line 76 | public abstract class LinkedAsyncAction
76  
77      /**
78       * Creates a new action with no parent. (You can add a parent
79 <     * later (but before forking) via <tt>reinitialize</tt>).
79 >     * later (but before forking) via {@code reinitialize}).
80       */
81      protected LinkedAsyncAction() {
82      }
83  
84      /**
85       * Creates a new action with the given parent. If the parent is
86 <     * non-null, this tasks registers with the parent, in which case,
86 >     * non-null, this task registers with the parent, in which case,
87       * the parent task cannot complete until this task completes.
88       * @param parent the parent task, or null if none
89       */
# Line 98 | Line 96 | public abstract class LinkedAsyncAction
96      /**
97       * Creates a new action with the given parent, optionally
98       * registering with the parent. If the parent is non-null and
99 <     * <tt>register</tt> is true, this tasks registers with the
99 >     * {@code register} is true, this task registers with the
100       * parent, in which case, the parent task cannot complete until
101       * this task completes.
102       * @param parent the parent task, or null if none
# Line 115 | Line 113 | public abstract class LinkedAsyncAction
113       * Creates a new action with the given parent, optionally
114       * registering with the parent, and setting the pending join count
115       * to the given value. If the parent is non-null and
116 <     * <tt>register</tt> is true, this tasks registers with the
116 >     * {@code register} is true, this task registers with the
117       * parent, in which case, the parent task cannot complete until
118       * this task completes. Setting the pending join count requires
119       * care -- it is correct only if child tasks do not themselves
# Line 138 | Line 136 | public abstract class LinkedAsyncAction
136      protected final void setRawResult(Void mustBeNull) { }
137  
138      /**
139 <     * Overridable callback action triggered by <tt>complete</tt>.  Upon
139 >     * Overridable callback action triggered by {@code complete}.  Upon
140       * invocation, all subtasks have completed.  After return, this
141 <     * task <tt>isDone</tt> and is joinable by other tasks. The
141 >     * task {@code isDone} and is joinable by other tasks. The
142       * default version of this method does nothing. But it may be
143       * overridden in subclasses to perform some action when this task
144       * is about to complete.
# Line 150 | Line 148 | public abstract class LinkedAsyncAction
148  
149      /**
150       * Overridable callback action triggered by
151 <     * <tt>completeExceptionally</tt>.  Upon invocation, this task has
151 >     * {@code completeExceptionally}.  Upon invocation, this task has
152       * aborted due to an exception (accessible via
153 <     * <tt>getException</tt>). If this method returns <tt>true</tt>,
153 >     * {@code getException}). If this method returns {@code true},
154       * the exception propagates to the current task's
155       * parent. Otherwise, normal completion is propagated.  The
156       * default version of this method does nothing and returns
157 <     * <tt>true</tt>.
157 >     * {@code true}.
158       * @return true if this task's exception should be propagated to
159 <     * this tasks parent.
159 >     * this task's parent
160       */
161      protected boolean onException() {
162          return true;
# Line 176 | Line 174 | public abstract class LinkedAsyncAction
174  
175      /**
176       * Completes this task. If the pending subtask completion count is
177 <     * zero, invokes <tt>onCompletion</tt>, then causes this task to
178 <     * be joinable (<tt>isDone</tt> becomes true), and then
179 <     * recursively applies to this tasks's parent, if it exists. If an
180 <     * exception is encountered in any <tt>onCompletion</tt>
177 >     * zero, invokes {@code onCompletion}, then causes this task to
178 >     * be joinable ({@code isDone} becomes true), and then
179 >     * recursively applies to this task's parent, if it exists. If an
180 >     * exception is encountered in any {@code onCompletion}
181       * invocation, that task and its ancestors
182 <     * <tt>completeExceptionally</tt>.
182 >     * {@code completeExceptionally}.
183       */
184      public final void complete() {
185          LinkedAsyncAction a = this;
# Line 205 | Line 203 | public abstract class LinkedAsyncAction
203      /**
204       * Completes this task abnormally. Unless this task already
205       * cancelled or aborted, upon invocation, this method invokes
206 <     * <tt>onException</tt>, and then, depending on its return value,
207 <     * completees parent (if one exists) exceptionally or normally.  To
206 >     * {@code onException}, and then, depending on its return value,
207 >     * completes parent (if one exists) exceptionally or normally.  To
208       * avoid unbounded exception loops, this method aborts if an
209 <     * exception is encountered in any <tt>onException</tt>
209 >     * exception is encountered in any {@code onException}
210       * invocation.
211       * @param ex the exception to throw when joining this task
212       * @throws NullPointerException if ex is null
213       * @throws Throwable if any invocation of
214 <     * <tt>onException</tt> does so.
214 >     * {@code onException} does so
215       */
216      public final void completeExceptionally(Throwable ex) {
217          LinkedAsyncAction a = this;
# Line 232 | Line 230 | public abstract class LinkedAsyncAction
230  
231      /**
232       * Returns this task's parent, or null if none.
233 <     * @return this task's parent, or null if none.
233 >     * @return this task's parent, or null if none
234       */
235      public final LinkedAsyncAction getParent() {
236          return parent;
# Line 240 | Line 238 | public abstract class LinkedAsyncAction
238  
239      /**
240       * Returns the number of subtasks that have not yet completed.
241 <     * @return the number of subtasks that have not yet completed.
241 >     * @return the number of subtasks that have not yet completed
242       */
243      public final int getPendingSubtaskCount() {
244          return getControlState();
# Line 341 | Line 339 | public abstract class LinkedAsyncAction
339          controlStateUpdater.decrementAndGet(this);
340      }
341  
344
342   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines