21 |
|
* #tryComplete}, if the pending action count is nonzero, it is |
22 |
|
* decremented; otherwise, the completion action is performed, and if |
23 |
|
* this completer itself has a completer, the process is continued |
24 |
< |
* with its completer. As is the case with most basic synchronization |
25 |
< |
* constructs, these methods affect only internal counts; they do not |
26 |
< |
* establish any further internal bookkeeping. In particular, the |
27 |
< |
* identities of pending tasks are not maintained. As illustrated |
28 |
< |
* below, you can create subclasses that do record some or all pended |
29 |
< |
* tasks or their results when needed. |
24 |
> |
* with its completer. As is the case with related synchronization |
25 |
> |
* components such as {@link Phaser} and {@link |
26 |
> |
* java.util.concurrent.Semaphore} these methods affect only internal |
27 |
> |
* counts; they do not establish any further internal bookkeeping. In |
28 |
> |
* particular, the identities of pending tasks are not maintained. As |
29 |
> |
* illustrated below, you can create subclasses that do record some or |
30 |
> |
* all pended tasks or their results when needed. |
31 |
|
* |
32 |
|
* <p>A concrete CountedCompleter class must define method {@link |
33 |
|
* #compute}, that should, in almost all use cases, invoke {@code |
34 |
< |
* tryComplete()} before returning. The class may also optionally |
34 |
> |
* tryComplete()} once before returning. The class may also optionally |
35 |
|
* override method {@link #onCompletion} to perform an action upon |
36 |
< |
* normal completion. |
36 |
> |
* normal completion, and method {@link #onExceptionalCompletion} to |
37 |
> |
* perform an action upon any exception. |
38 |
|
* |
39 |
|
* <p>A CountedCompleter that does not itself have a completer (i.e., |
40 |
|
* one for which {@link #getCompleter} returns {@code null}) can be |
46 |
|
* {@link #complete}, {@link ForkJoinTask#cancel}, {@link |
47 |
|
* ForkJoinTask#completeExceptionally} or upon exceptional completion |
48 |
|
* of method {@code compute}. Upon any exceptional completion, the |
49 |
< |
* exception is relayed to a task's completer (and its completer, and |
50 |
< |
* so on), if one exists and it has not otherwise already completed. |
49 |
> |
* exception may be relayed to a task's completer (and its completer, |
50 |
> |
* and so on), if one exists and it has not otherwise already |
51 |
> |
* completed. |
52 |
|
* |
53 |
|
* <p><b>Sample Usages.</b> |
54 |
|
* |
240 |
|
* @author Doug Lea |
241 |
|
*/ |
242 |
|
public abstract class CountedCompleter extends ForkJoinTask<Void> { |
243 |
+ |
private static final long serialVersionUID = 5232453752276485070L; |
244 |
+ |
|
245 |
|
/** This task's completer, or null if none */ |
246 |
|
final CountedCompleter completer; |
247 |
|
/** The number of pending tasks until completion */ |
284 |
|
public abstract void compute(); |
285 |
|
|
286 |
|
/** |
287 |
< |
* Executes the completion action when method {@link #tryComplete} |
288 |
< |
* is invoked and there are no pending counts, or when the |
289 |
< |
* unconditional method {@link #complete} is invoked. By default, |
290 |
< |
* this method does nothing. |
287 |
> |
* Performs an action when method {@link #tryComplete} is invoked |
288 |
> |
* and there are no pending counts, or when the unconditional |
289 |
> |
* method {@link #complete} is invoked. By default, this method |
290 |
> |
* does nothing. |
291 |
|
* |
292 |
|
* @param caller the task invoking this method (which may |
293 |
|
* be this task itself). |
296 |
|
} |
297 |
|
|
298 |
|
/** |
299 |
+ |
* Performs an action when method {@link #completeExceptionally} |
300 |
+ |
* is invoked or method {@link #compute} throws an exception, and |
301 |
+ |
* this task has not otherwise already completed normally. On |
302 |
+ |
* entry to this method, this task {@link |
303 |
+ |
* ForkJoinTask#isCompletedAbnormally}. The return value of this |
304 |
+ |
* method controls further propagation: If {@code true} and this |
305 |
+ |
* task has a completer, then this completer is also completed |
306 |
+ |
* exceptionally. The default implementation of this method does |
307 |
+ |
* nothing except return {@code true}. |
308 |
+ |
* |
309 |
+ |
* @param ex the exception |
310 |
+ |
* @param caller the task invoking this method (which may |
311 |
+ |
* be this task itself). |
312 |
+ |
* @return true if this exception should be propagated to this |
313 |
+ |
* tasks completer, if one exists. |
314 |
+ |
*/ |
315 |
+ |
public boolean onExceptionalCompletion(Throwable ex, CountedCompleter caller) { |
316 |
+ |
return true; |
317 |
+ |
} |
318 |
+ |
|
319 |
+ |
/** |
320 |
|
* Returns the completer established in this task's constructor, |
321 |
|
* or {@code null} if none. |
322 |
|
* |
373 |
|
* else marks this task as complete. |
374 |
|
*/ |
375 |
|
public final void tryComplete() { |
376 |
< |
for (CountedCompleter a = this, s = a;;) { |
377 |
< |
int c; |
376 |
> |
CountedCompleter a = this, s = a; |
377 |
> |
for (int c;;) { |
378 |
|
if ((c = a.pending) == 0) { |
379 |
|
a.onCompletion(s); |
380 |
|
if ((a = (s = a).completer) == null) { |
406 |
|
} |
407 |
|
|
408 |
|
/** |
409 |
+ |
* Support for FJT exception propagation |
410 |
+ |
*/ |
411 |
+ |
void internalPropagateException(Throwable ex) { |
412 |
+ |
CountedCompleter a = this, s = a; |
413 |
+ |
while (a.onExceptionalCompletion(ex, s) && |
414 |
+ |
(a = (s = a).completer) != null && a.status >= 0) |
415 |
+ |
a.recordExceptionalCompletion(ex); |
416 |
+ |
} |
417 |
+ |
|
418 |
+ |
/** |
419 |
|
* Implements execution conventions for CountedCompleters |
420 |
|
*/ |
421 |
|
protected final boolean exec() { |
435 |
|
*/ |
436 |
|
protected final void setRawResult(Void mustBeNull) { } |
437 |
|
|
402 |
– |
/** |
403 |
– |
* Support for FJT exception propagation |
404 |
– |
*/ |
405 |
– |
final ForkJoinTask<?> internalGetCompleter() { return completer; } |
406 |
– |
|
438 |
|
// Unsafe mechanics |
439 |
|
private static final sun.misc.Unsafe U; |
440 |
|
private static final long PENDING; |