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

Comparing jsr166/src/jsr166y/CountedCompleter.java (file contents):
Revision 1.13 by jsr166, Sun Nov 18 18:03:10 2012 UTC vs.
Revision 1.14 by dl, Mon Nov 19 18:12:42 2012 UTC

# Line 7 | Line 7
7   package jsr166y;
8  
9   /**
10 < * A {@link ForkJoinTask} with a completion action
11 < * performed when triggered and there are no remaining pending
12 < * actions. Uses of CountedCompleter are similar to those of other
13 < * completion based components (such as {@link
14 < * java.nio.channels.CompletionHandler}) except that multiple
15 < * <em>pending</em> completions may be necessary to trigger the {@link
16 < * #onCompletion} action, not just one. Unless initialized otherwise,
17 < * the {@link #getPendingCount pending count} starts at zero, but may
18 < * be (atomically) changed using methods {@link #setPendingCount},
19 < * {@link #addToPendingCount}, and {@link
10 > * A {@link ForkJoinTask} with a completion action performed when
11 > * triggered and there are no remaining pending
12 > * actions. CountedCompleters are in general more robust in the
13 > * presence of subtask stalls and blockage than are other forms for
14 > * ForkJoinTasks, but are in general less intuitive to program.  Uses
15 > * of CountedCompleter are similar to those of other completion based
16 > * components (such as {@link java.nio.channels.CompletionHandler})
17 > * except that multiple <em>pending</em> completions may be necessary
18 > * to trigger the {@link #onCompletion} action, not just one. Unless
19 > * initialized otherwise, the {@link #getPendingCount pending count}
20 > * starts at zero, but may be (atomically) changed using methods
21 > * {@link #setPendingCount}, {@link #addToPendingCount}, and {@link
22   * #compareAndSetPendingCount}. Upon invocation of {@link
23   * #tryComplete}, if the pending action count is nonzero, it is
24   * decremented; otherwise, the completion action is performed, and if
# Line 28 | Line 30 | package jsr166y;
30   * internal bookkeeping. In particular, the identities of pending
31   * tasks are not maintained. As illustrated below, you can create
32   * subclasses that do record some or all pending tasks or their
33 < * results when needed.
33 > * results when needed. Because CountedCompleters provide only basic
34 > * synchronization mechanisms, it may be useful to create further
35 > * abstract subclasses that maintain linkages and fields and support
36 > * methods appropriate for a set of related usages.
37   *
38   * <p>A concrete CountedCompleter class must define method {@link
39 < * #compute}, that should, in almost all use cases, invoke {@code
40 < * tryComplete()} once before returning. The class may also optionally
41 < * override method {@link #onCompletion} to perform an action upon
42 < * normal completion, and method {@link #onExceptionalCompletion} to
43 < * perform an action upon any exception.
39 > * #compute}, that should in most cases (as illustrated below), invoke
40 > * {@code tryComplete()} once before returning. The class may also
41 > * optionally override method {@link #onCompletion} to perform an
42 > * action upon normal completion, and method {@link
43 > * #onExceptionalCompletion} to perform an action upon any exception.
44   *
45   * <p>CountedCompleters most often do not bear results, in which case
46   * they are normally declared as {@code CountedCompleter<Void>}, and
47   * will always return {@code null} as a result value.  In other cases,
48   * you should override method {@link #getRawResult} to provide a
49 < * result from {@code join(), invoke()}, and related methods. (Method
50 < * {@link #setRawResult} by default plays no role in CountedCompleters
51 < * but may be overridden for example to maintain fields holding result
52 < * data.)
49 > * result from {@code join(), invoke()}, and related methods.  In
50 > * general, this method should return the value of a field (or a
51 > * function of one or more fields) of the CountedCompleter object that
52 > * holds the result upon completion. Method {@link #setRawResult} by
53 > * default plays no role in CountedCompleters.  It is possible, but
54 > * not usually applicable, to override this method to maintain other
55 > * objects or fields holding result data.
56   *
57   * <p>A CountedCompleter that does not itself have a completer (i.e.,
58   * one for which {@link #getCompleter} returns {@code null}) can be
# Line 58 | Line 66 | package jsr166y;
66   * of method {@code compute}. Upon any exceptional completion, the
67   * exception may be relayed to a task's completer (and its completer,
68   * and so on), if one exists and it has not otherwise already
69 < * completed.
69 > * completed. Similarly, cancelling an internal CountedCompleter has
70 > * only a local effect on that completer, so is not often useful.
71   *
72   * <p><b>Sample Usages.</b>
73   *
# Line 86 | Line 95 | package jsr166y;
95   * pair of subtasks to finish triggers completion of its parent
96   * (because no result combination is performed, the default no-op
97   * implementation of method {@code onCompletion} is not overridden). A
98 < * static utility method sets up the base task and invokes it:
98 > * static utility method sets up the base task and invokes it
99 > * (here, implicitly using the {@link ForkJoinPool#commonPool()}).
100   *
101   * <pre> {@code
102   * class MyOperation<E> { void apply(E e) { ... }  }
103   *
104   * class ForEach<E> extends CountedCompleter<Void> {
105   *
106 < *     public static <E> void forEach(ForkJoinPool pool, E[] array, MyOperation<E> op) {
107 < *         pool.invoke(new ForEach<E>(null, array, op, 0, array.length));
106 > *     public static <E> void forEach(E[] array, MyOperation<E> op) {
107 > *         new ForEach<E>(null, array, op, 0, array.length).invoke();
108   *     }
109   *
110   *     final E[] array; final MyOperation<E> op; final int lo, hi;
# Line 221 | Line 231 | package jsr166y;
231   *     }
232   *     public E getRawResult() { return result; }
233   *
234 < *     public static <E> E mapReduce(ForkJoinPool pool, E[] array,
235 < *                                   MyMapper<E> mapper, MyReducer<E> reducer) {
236 < *         return pool.invoke(new MapReducer<E>(null, array, mapper,
227 < *                                              reducer, 0, array.length));
234 > *     public static <E> E mapReduce(E[] array, MyMapper<E> mapper, MyReducer<E> reducer) {
235 > *         return new MapReducer<E>(null, array, mapper, reducer,
236 > *                                  0, array.length).invoke();
237   *     }
238   * } }</pre>
239   *
240 + * Here, method {@code onCompletion} takes a form common to many
241 + * completion designs that combine results. This callback-style method
242 + * is triggered once per task, in either of the two different contexts
243 + * in which the pending count is, or becomes, zero: (1) by a task
244 + * itself, if its pending count is zero upon invocation of {@code
245 + * tryComplete}, or (2) by any of its subtasks when they complete and
246 + * decrement the pending count to zero. The {@code caller} argument
247 + * distinguishes cases.  Most often, when the caller is {@code this},
248 + * no action is necessary. Otherwise the caller argument can be used
249 + * (usually via a cast) to supply a value (and/or links to other
250 + * values) to be combined.  Asuuming proper use of pending counts, the
251 + * actions inside {@code onCompletion} occur (once) upon completion of
252 + * a task and its subtasks. No additional synchronization is required
253 + * within this method to ensure thread safety of accesses to fields of
254 + * this task or other completed tasks.
255 + *
256 + * <p><b>Searching.</b> A tree of CountedCompleters can search for a
257 + * value or property in different parts of a data structure, and
258 + * report a result in an {@link java.util.concurrent.AtomicReference}
259 + * as soon as one is found. The others can poll the result to avoid
260 + * unnecessary work. (You could additionally {@link #cancel} other
261 + * tasks, but it is usually simpler and more efficient to just let
262 + * them notice that the result is set and if so skip further
263 + * processing.)  Illustrating again with an array using full
264 + * partitioning (again, in practice, leaf tasks will almost always
265 + * process more than one element):
266 + *
267 + * <pre> {@code
268 + * class Searcher<E> extends CountedCompleter<E> {
269 + *     final E[] array; final AtomicReference<E> result; final int lo, hi;
270 + *     Searcher(CountedCompleter<?> p, E[] array, AtomicReference<E> result, int lo, int hi) {
271 + *         super(p);
272 + *         this.array = array; this.result = result; this.lo = lo; this.hi = hi;
273 + *     }
274 + *     public E getRawResult() { return result.get(); }
275 + *     public void compute() { // similar to ForEach version 3
276 + *         int l = lo,  h = hi;
277 + *         while (h - l >= 2 && result.get() == null) {
278 + *             int mid = (l + h) >>> 1;
279 + *             addToPendingCount(1);
280 + *             new Searcher(this, array, result, mid, h).fork();
281 + *             h = mid;
282 + *         }
283 + *         if (h > l && result.get() == null && matches(array[l]) &&
284 + *             result.compareAndSet(null, array[l]))
285 + *             getRoot().quietlyComplete(); // root task is now joinable
286 + *
287 + *         tryComplete(); // normally complete whether or not found
288 + *     }
289 + *     boolean matches(E e) { ... } // return true if found
290 + *
291 + *     public static <E> E search(E[] array) {
292 + *         return new Searcher<E>(null, array, new AtomicReference<E>(), 0, array.length).invoke();
293 + *     }
294 + *}}</pre>
295 + *
296 + * In this example, as well as others in which tasks have no other
297 + * effects except to compareAndSet a common result, the trailing
298 + * unconditional invocation of {@code tryComplete} could be made
299 + * conditional ({@code if (result.get() == null) tryComplete();})
300 + * because no further bookkeeping is required to manage completions
301 + * once the root task completes.
302 + *
303   * <p><b>Triggers.</b> Some CountedCompleters are themselves never
304   * forked, but instead serve as bits of plumbing in other designs;
305   * including those in which the completion of one of more async tasks
# Line 298 | Line 370 | public abstract class CountedCompleter<T
370       * Performs an action when method {@link #tryComplete} is invoked
371       * and there are no pending counts, or when the unconditional
372       * method {@link #complete} is invoked.  By default, this method
373 <     * does nothing.
373 >     * does nothing. You can distinguish cases by checking the
374 >     * identity of the given caller argument. If not equal to {@code
375 >     * this}, then it is typically a subtask that may contain results
376 >     * (and/or links to other results) to combine.
377       *
378       * @param caller the task invoking this method (which may
379       * be this task itself).
# Line 414 | Line 489 | public abstract class CountedCompleter<T
489      /**
490       * Regardless of pending count, invokes {@link #onCompletion},
491       * marks this task as complete and further triggers {@link
492 <     * #tryComplete} on this task's completer, if one exists. This
418 <     * method may be useful when forcing completion as soon as any one
419 <     * (versus all) of several subtask results are obtained.  The
492 >     * #tryComplete} on this task's completer, if one exists.  The
493       * given rawResult is used as an argument to {@link #setRawResult}
494 <     * before marking this task as complete; its value is meaningful
495 <     * only for classes overriding {@code setRawResult}.
494 >     * before invoking {@link #onCompletion} or marking this task as
495 >     * complete; its value is meaningful only for classes overriding
496 >     * {@code setRawResult}.
497 >     *
498 >     * <p>This method may be useful when forcing completion as soon as
499 >     * any one (versus all) of several subtask results are obtained.
500 >     * However, in the common (and recommended) case in which {@code
501 >     * setRawResult} is not overridden, this effect can be obtained
502 >     * more simply using {@code getRoot().quietlyComplete();}.
503       *
504       * @param rawResult the raw result
505       */
506      public void complete(T rawResult) {
507          CountedCompleter<?> p;
428        onCompletion(this);
508          setRawResult(rawResult);
509 +        onCompletion(this);
510          quietlyComplete();
511          if ((p = completer) != null)
512              p.tryComplete();
# Line 462 | Line 542 | public abstract class CountedCompleter<T
542      /**
543       * A method that result-bearing CountedCompleters may optionally
544       * use to help maintain result data.  By default, does nothing.
545 +     * If this method is overridden to update existing objects or
546 +     * fields, then it must in general be defined to be thread-safe.
547       */
548      protected void setRawResult(T t) { }
549  
# Line 470 | Line 552 | public abstract class CountedCompleter<T
552      private static final long PENDING;
553      static {
554          try {
555 <            U = getUnsafe();
555 >            U = sun.misc.Unsafe.getUnsafe();
556              PENDING = U.objectFieldOffset
557                  (CountedCompleter.class.getDeclaredField("pending"));
558          } catch (Exception e) {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines