126 |
|
* op.apply(array[lo]); |
127 |
|
* tryComplete(); |
128 |
|
* } |
129 |
< |
* } }</pre> |
129 |
> |
* }}</pre> |
130 |
|
* |
131 |
|
* This design can be improved by noticing that in the recursive case, |
132 |
|
* the task has nothing to do after forking its right task, so can |
133 |
|
* directly invoke its left task before returning. (This is an analog |
134 |
|
* of tail recursion removal.) Also, because the task returns upon |
135 |
|
* executing its left task (rather than falling through to invoke |
136 |
< |
* tryComplete) the pending count is set to one: |
136 |
> |
* {@code tryComplete}) the pending count is set to one: |
137 |
|
* |
138 |
|
* <pre> {@code |
139 |
|
* class ForEach<E> ... |
277 |
|
* } |
278 |
|
* public void onCompletion(CountedCompleter<?> caller) { |
279 |
|
* if (caller != this) { |
280 |
< |
* MapReducer<E> child = (MapReducer<E>)caller; |
281 |
< |
* MapReducer<E> sib = child.sibling; |
282 |
< |
* if (sib == null || sib.result == null) |
283 |
< |
* result = child.result; |
284 |
< |
* else |
285 |
< |
* result = reducer.apply(child.result, sib.result); |
280 |
> |
* MapReducer<E> child = (MapReducer<E>)caller; |
281 |
> |
* MapReducer<E> sib = child.sibling; |
282 |
> |
* if (sib == null || sib.result == null) |
283 |
> |
* result = child.result; |
284 |
> |
* else |
285 |
> |
* result = reducer.apply(child.result, sib.result); |
286 |
|
* } |
287 |
|
* } |
288 |
|
* public E getRawResult() { return result; } |
291 |
|
* return new MapReducer<E>(null, array, mapper, reducer, |
292 |
|
* 0, array.length).invoke(); |
293 |
|
* } |
294 |
< |
* } }</pre> |
294 |
> |
* }}</pre> |
295 |
|
* |
296 |
|
* Here, method {@code onCompletion} takes a form common to many |
297 |
|
* completion designs that combine results. This callback-style method |
388 |
|
* Creates a new CountedCompleter with the given completer |
389 |
|
* and initial pending count. |
390 |
|
* |
391 |
< |
* @param completer this tasks completer, or {@code null} if none |
391 |
> |
* @param completer this task's completer, or {@code null} if none |
392 |
|
* @param initialPendingCount the initial pending count |
393 |
|
*/ |
394 |
|
protected CountedCompleter(CountedCompleter<?> completer, |
401 |
|
* Creates a new CountedCompleter with the given completer |
402 |
|
* and an initial pending count of zero. |
403 |
|
* |
404 |
< |
* @param completer this tasks completer, or {@code null} if none |
404 |
> |
* @param completer this task's completer, or {@code null} if none |
405 |
|
*/ |
406 |
|
protected CountedCompleter(CountedCompleter<?> completer) { |
407 |
|
this.completer = completer; |
422 |
|
|
423 |
|
/** |
424 |
|
* Performs an action when method {@link #tryComplete} is invoked |
425 |
< |
* and there are no pending counts, or when the unconditional |
425 |
> |
* and the pending count is zero, or when the unconditional |
426 |
|
* method {@link #complete} is invoked. By default, this method |
427 |
|
* does nothing. You can distinguish cases by checking the |
428 |
|
* identity of the given caller argument. If not equal to {@code |
450 |
|
* @param caller the task invoking this method (which may |
451 |
|
* be this task itself). |
452 |
|
* @return true if this exception should be propagated to this |
453 |
< |
* tasks completer, if one exists. |
453 |
> |
* task's completer, if one exists. |
454 |
|
*/ |
455 |
|
public boolean onExceptionalCompletion(Throwable ex, CountedCompleter<?> caller) { |
456 |
|
return true; |
661 |
|
} |
662 |
|
|
663 |
|
/** |
664 |
< |
* Support for FJT exception propagation |
664 |
> |
* Supports ForkJoinTask exception propagation. |
665 |
|
*/ |
666 |
|
void internalPropagateException(Throwable ex) { |
667 |
|
CountedCompleter<?> a = this, s = a; |
671 |
|
} |
672 |
|
|
673 |
|
/** |
674 |
< |
* Implements execution conventions for CountedCompleters |
674 |
> |
* Implements execution conventions for CountedCompleters. |
675 |
|
*/ |
676 |
|
protected final boolean exec() { |
677 |
|
compute(); |