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

Comparing jsr166/src/test/loops/BinaryAsyncAction.java (file contents):
Revision 1.5 by jsr166, Sat Jan 28 04:41:18 2012 UTC vs.
Revision 1.17 by dl, Sat Sep 12 18:11:24 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.concurrent.*;
# Line 13 | Line 13 | import java.util.concurrent.atomic.*;
13   * have smaller stack space footprints and faster completion mechanics
14   * but higher per-task footprints. Compared to LinkedAsyncActions,
15   * BinaryAsyncActions are simpler to use and have less overhead in
16 < * typical uasges but are restricted to binary computation trees.
16 > * typical usages but are restricted to binary computation trees.
17   *
18 < * <p> Upon construction, an BinaryAsyncAction does not bear any
18 > * <p>Upon construction, a BinaryAsyncAction does not bear any
19   * linkages. For non-root tasks, links must be established using
20 < * method <tt>linkSubtasks</tt> before use.
20 > * method {@link #linkSubtasks} before use.
21   *
22 < * <p> <b>Sample Usage.</b>  A version of Fibonacci:
22 > * <p><b>Sample Usage.</b>  A version of Fibonacci:
23   * <pre>
24   * class Fib extends BinaryAsyncAction {
25   *   final int n;
# Line 27 | Line 27 | import java.util.concurrent.atomic.*;
27   *   Fib(int n) { this.n = n; }
28   *   protected void compute() {
29   *     if (n &gt; 1) {
30 < *        linkAndForkSubtasks(new Fib(n-1), new Fib(n-2));
30 > *       linkAndForkSubtasks(new Fib(n-1), new Fib(n-2));
31   *     else {
32 < *        result = n; // fib(0)==0; fib(1)==1
33 < *        complete();
32 > *       result = n; // fib(0)==0; fib(1)==1
33 > *       complete();
34   *     }
35   *   }
36   *   protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) {
37 < *      result = ((Fib)x).result + ((Fib)y).result;
37 > *     result = ((Fib)x).result + ((Fib)y).result;
38   *   }
39   * }
40   * </pre>
41 < * An alternative, and usually faster strategy is to instead use a
41 > * An alternative, and usually faster, strategy is to instead use a
42   * loop to fork subtasks:
43   * <pre>
44   *   protected void compute() {
45   *     Fib f = this;
46   *     while (f.n &gt; 1) {
47 < *        Fib left = new Fib(f.n - 1);
48 < *        Fib right = new Fib(f.n - 2);
49 < *        f.linkSubtasks(left, right);
50 < *        right.fork(); // fork right
51 < *        f = left;     // loop on left
47 > *       Fib left = new Fib(f.n - 1);
48 > *       Fib right = new Fib(f.n - 2);
49 > *       f.linkSubtasks(left, right);
50 > *       right.fork(); // fork right
51 > *       f = left;     // loop on left
52   *     }
53   *     f.result = f.n;
54   *     f.complete();
# Line 57 | Line 57 | import java.util.concurrent.atomic.*;
57   * </pre>
58   */
59   public abstract class BinaryAsyncAction extends ForkJoinTask<Void> {
60    private volatile int controlState;
61
62    static final AtomicIntegerFieldUpdater<BinaryAsyncAction> controlStateUpdater =
63        AtomicIntegerFieldUpdater.newUpdater(BinaryAsyncAction.class, "controlState");
60  
61      /**
62       * Parent to propagate completion; nulled after completion to
# Line 75 | Line 71 | public abstract class BinaryAsyncAction
71  
72      /**
73       * Creates a new action. Unless this is a root task, you will need
74 <     * to link it using method <tt>linkSubtasks</tt> before forking as
74 >     * to link it using method {@link #linkSubtasks} before forking as
75       * a subtask.
76       */
77      protected BinaryAsyncAction() {
# Line 89 | Line 85 | public abstract class BinaryAsyncAction
85       * as parent, and each other as siblings.
86       * @param x one subtask
87       * @param y the other subtask
88 <     * @throws NullPointerException if either argument is null.
88 >     * @throws NullPointerException if either argument is null
89       */
90      public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) {
91          x.parent = y.parent = this;
# Line 98 | Line 94 | public abstract class BinaryAsyncAction
94      }
95  
96      /**
97 <     * Overridable callback action triggered upon <tt>complete</tt> of
97 >     * Overridable callback action triggered upon {@code complete} of
98       * subtasks.  Upon invocation, both subtasks have completed.
99 <     * After return, this task <tt>isDone</tt> and is joinable by
99 >     * After return, this task {@code isDone} and is joinable by
100       * other tasks. The default version of this method does nothing.
101       * But it may be overridden in subclasses to perform some action
102       * (for example a reduction) when this task is completes.
# Line 112 | Line 108 | public abstract class BinaryAsyncAction
108  
109      /**
110       * Overridable callback action triggered by
111 <     * <tt>completeExceptionally</tt>.  Upon invocation, this task has
111 >     * {@code completeExceptionally}.  Upon invocation, this task has
112       * aborted due to an exception (accessible via
113 <     * <tt>getException</tt>). If this method returns <tt>true</tt>,
113 >     * {@code getException}). If this method returns {@code true},
114       * the exception propagates to the current task's
115       * parent. Otherwise, normal completion is propagated.  The
116       * default version of this method does nothing and returns
117 <     * <tt>true</tt>.
117 >     * {@code true}.
118       * @return true if this task's exception should be propagated to
119 <     * this tasks parent.
119 >     * this task's parent
120       */
121      protected boolean onException() {
122          return true;
123      }
124  
125      /**
126 <     * Equivalent in effect to invoking <tt>linkSubtasks</tt> and then
126 >     * Equivalent in effect to invoking {@link #linkSubtasks} and then
127       * forking both tasks.
128       * @param x one subtask
129       * @param y the other subtask
# Line 156 | Line 152 | public abstract class BinaryAsyncAction
152  
153      /**
154       * Completes this task, and if this task has a sibling that is
155 <     * also complete, invokes <tt>onComplete</tt> of parent task, and so
155 >     * also complete, invokes {@code onComplete} of parent task, and so
156       * on. If an exception is encountered, tasks instead
157 <     * <tt>completeExceptionally</tt>.
157 >     * {@code completeExceptionally}.
158       */
159      public final void complete() {
160          // todo: Use tryUnfork without possibly blowing stack
# Line 169 | Line 165 | public abstract class BinaryAsyncAction
165              a.sibling = null;
166              a.parent = null;
167              a.completeThis();
168 <            if (p == null || p.compareAndSetControlState(0, 1))
168 >            if (p == null || p.markForkJoinTask())
169                  break;
170              try {
171                  p.onComplete(a, s);
# Line 184 | Line 180 | public abstract class BinaryAsyncAction
180      /**
181       * Completes this task abnormally. Unless this task already
182       * cancelled or aborted, upon invocation, this method invokes
183 <     * <tt>onException</tt>, and then, depending on its return value,
184 <     * completees parent (if one exists) exceptionally or normally.  To
183 >     * {@code onException}, and then, depending on its return value,
184 >     * completes parent (if one exists) exceptionally or normally.  To
185       * avoid unbounded exception loops, this method aborts if an
186 <     * exception is encountered in any <tt>onException</tt>
186 >     * exception is encountered in any {@code onException}
187       * invocation.
188       * @param ex the exception to throw when joining this task
189       * @throws NullPointerException if ex is null
190       * @throws Throwable if any invocation of
191 <     * <tt>onException</tt> does so.
191 >     * {@code onException} does so
192       */
193      public final void completeExceptionally(Throwable ex) {
194          BinaryAsyncAction a = this;
# Line 209 | Line 205 | public abstract class BinaryAsyncAction
205      /**
206       * Returns this task's parent, or null if none or this task
207       * is already complete.
208 <     * @return this task's parent, or null if none.
208 >     * @return this task's parent, or null if none
209       */
210      public final BinaryAsyncAction getParent() {
211          return parent;
# Line 218 | Line 214 | public abstract class BinaryAsyncAction
214      /**
215       * Returns this task's sibling, or null if none or this task is
216       * already complete.
217 <     * @return this task's sibling, or null if none.
217 >     * @return this task's sibling, or null if none
218       */
219      public BinaryAsyncAction getSibling() {
220          return sibling;
# Line 233 | Line 229 | public abstract class BinaryAsyncAction
229          super.reinitialize();
230      }
231  
232 + <<<<<<< BinaryAsyncAction.java
233 + =======
234      /**
235       * Gets the control state, which is initially zero, or negative if
236       * this task has completed or cancelled. Once negative, the value
# Line 267 | Line 265 | public abstract class BinaryAsyncAction
265      }
266  
267      /**
268 <     * Sets the control state to the given value,
268 >     * Increments the control state.
269       * @param value the new value
270       */
271      protected final void incrementControlState() {
# Line 275 | Line 273 | public abstract class BinaryAsyncAction
273      }
274  
275      /**
276 <     * Decrement the control state
276 >     * Decrements the control state.
277       * @return true if successful
278       */
279      protected final void decrementControlState() {
280          controlStateUpdater.decrementAndGet(this);
281      }
282 + >>>>>>> 1.14
283  
284   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines