6 |
|
|
7 |
|
package jsr166y; |
8 |
|
|
9 |
– |
import java.util.concurrent.*; |
9 |
|
import java.io.Serializable; |
10 |
|
import java.util.Collection; |
11 |
|
import java.util.Collections; |
13 |
|
import java.util.RandomAccess; |
14 |
|
import java.util.Map; |
15 |
|
import java.util.WeakHashMap; |
16 |
+ |
import java.util.concurrent.Callable; |
17 |
+ |
import java.util.concurrent.CancellationException; |
18 |
+ |
import java.util.concurrent.ExecutionException; |
19 |
+ |
import java.util.concurrent.Executor; |
20 |
+ |
import java.util.concurrent.ExecutorService; |
21 |
+ |
import java.util.concurrent.Future; |
22 |
+ |
import java.util.concurrent.RejectedExecutionException; |
23 |
+ |
import java.util.concurrent.RunnableFuture; |
24 |
+ |
import java.util.concurrent.TimeUnit; |
25 |
+ |
import java.util.concurrent.TimeoutException; |
26 |
|
|
27 |
|
/** |
28 |
|
* Abstract base class for tasks that run within a {@link ForkJoinPool}. |
110 |
|
* result in exceptions or errors, possibly including |
111 |
|
* {@code ClassCastException}. |
112 |
|
* |
113 |
+ |
* <p>Method {@link #join} and its variants are appropriate for use |
114 |
+ |
* only when completion dependencies are acyclic; that is, the |
115 |
+ |
* parallel computation can be described as a directed acyclic graph |
116 |
+ |
* (DAG). Otherwise, executions may encounter a form of deadlock as |
117 |
+ |
* tasks cyclically wait for each other. However, this framework |
118 |
+ |
* supports other methods and techniques (for example the use of |
119 |
+ |
* {@link Phaser}, {@link #helpQuiesce}, and {@link #complete}) that |
120 |
+ |
* may be of use in constructing custom subclasses for problems that |
121 |
+ |
* are not statically structured as DAGs. |
122 |
+ |
* |
123 |
|
* <p>Most base support methods are {@code final}, to prevent |
124 |
|
* overriding of implementations that are intrinsically tied to the |
125 |
|
* underlying lightweight task scheduling framework. Developers |
257 |
|
* |
258 |
|
* @return status on exit |
259 |
|
*/ |
260 |
< |
final int internalAwaitDone(long millis) { |
260 |
> |
final int internalAwaitDone(long millis, int nanos) { |
261 |
|
int s; |
262 |
|
if ((s = status) >= 0) { |
263 |
|
try { |
264 |
|
synchronized (this) { |
265 |
|
if (UNSAFE.compareAndSwapInt(this, statusOffset, s,SIGNAL)) |
266 |
< |
wait(millis, 0); |
266 |
> |
wait(millis, nanos); |
267 |
|
} |
268 |
|
} catch (InterruptedException ie) { |
269 |
|
cancelIfTerminating(); |
340 |
|
} |
341 |
|
|
342 |
|
/** |
343 |
< |
* Returns the result of the computation when it {@link #isDone is done}. |
344 |
< |
* This method differs from {@link #get()} in that |
343 |
> |
* Returns the result of the computation when it {@link #isDone is |
344 |
> |
* done}. This method differs from {@link #get()} in that |
345 |
|
* abnormal completion results in {@code RuntimeException} or |
346 |
< |
* {@code Error}, not {@code ExecutionException}. |
346 |
> |
* {@code Error}, not {@code ExecutionException}, and that |
347 |
> |
* interrupts of the calling thread do <em>not</em> cause the |
348 |
> |
* method to abruptly return by throwing {@code |
349 |
> |
* InterruptedException}. |
350 |
|
* |
351 |
|
* @return the computed result |
352 |
|
*/ |
388 |
|
* unprocessed. |
389 |
|
* |
390 |
|
* <p>This method may be invoked only from within {@code |
391 |
< |
* ForkJoinTask} computations (as may be determined using method |
391 |
> |
* ForkJoinPool} computations (as may be determined using method |
392 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
393 |
|
* result in exceptions or errors, possibly including {@code |
394 |
|
* ClassCastException}. |
416 |
|
* normally or exceptionally, or left unprocessed. |
417 |
|
* |
418 |
|
* <p>This method may be invoked only from within {@code |
419 |
< |
* ForkJoinTask} computations (as may be determined using method |
419 |
> |
* ForkJoinPool} computations (as may be determined using method |
420 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
421 |
|
* result in exceptions or errors, possibly including {@code |
422 |
|
* ClassCastException}. |
471 |
|
* unprocessed. |
472 |
|
* |
473 |
|
* <p>This method may be invoked only from within {@code |
474 |
< |
* ForkJoinTask} computations (as may be determined using method |
474 |
> |
* ForkJoinPool} computations (as may be determined using method |
475 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
476 |
|
* result in exceptions or errors, possibly including {@code |
477 |
|
* ClassCastException}. |
523 |
|
|
524 |
|
/** |
525 |
|
* Attempts to cancel execution of this task. This attempt will |
526 |
< |
* fail if the task has already completed, has already been |
527 |
< |
* cancelled, or could not be cancelled for some other reason. If |
528 |
< |
* successful, and this task has not started when cancel is |
529 |
< |
* called, execution of this task is suppressed, {@link |
530 |
< |
* #isCancelled} will report true, and {@link #join} will result |
531 |
< |
* in a {@code CancellationException} being thrown. |
526 |
> |
* fail if the task has already completed or could not be |
527 |
> |
* cancelled for some other reason. If successful, and this task |
528 |
> |
* has not started when {@code cancel} is called, execution of |
529 |
> |
* this task is suppressed. After this method returns |
530 |
> |
* successfully, unless there is an intervening call to {@link |
531 |
> |
* #reinitialize}, subsequent calls to {@link #isCancelled}, |
532 |
> |
* {@link #isDone}, and {@code cancel} will return {@code true} |
533 |
> |
* and calls to {@link #join} and related methods will result in |
534 |
> |
* {@code CancellationException}. |
535 |
|
* |
536 |
|
* <p>This method may be overridden in subclasses, but if so, must |
537 |
< |
* still ensure that these minimal properties hold. In particular, |
538 |
< |
* the {@code cancel} method itself must not throw exceptions. |
537 |
> |
* still ensure that these properties hold. In particular, the |
538 |
> |
* {@code cancel} method itself must not throw exceptions. |
539 |
|
* |
540 |
|
* <p>This method is designed to be invoked by <em>other</em> |
541 |
|
* tasks. To terminate the current task, you can just return or |
542 |
|
* throw an unchecked exception from its computation method, or |
543 |
|
* invoke {@link #completeExceptionally}. |
544 |
|
* |
545 |
< |
* @param mayInterruptIfRunning this value is ignored in the |
546 |
< |
* default implementation because tasks are not |
547 |
< |
* cancelled via interruption |
545 |
> |
* @param mayInterruptIfRunning this value has no effect in the |
546 |
> |
* default implementation because interrupts are not used to |
547 |
> |
* control cancellation. |
548 |
|
* |
549 |
|
* @return {@code true} if this task is now cancelled |
550 |
|
*/ |
720 |
|
*/ |
721 |
|
public final V get(long timeout, TimeUnit unit) |
722 |
|
throws InterruptedException, ExecutionException, TimeoutException { |
698 |
– |
Thread t = Thread.currentThread(); |
699 |
– |
ForkJoinPool pool; |
700 |
– |
if (t instanceof ForkJoinWorkerThread) { |
701 |
– |
ForkJoinWorkerThread w = (ForkJoinWorkerThread) t; |
702 |
– |
if (status >= 0 && w.unpushTask(this)) |
703 |
– |
quietlyExec(); |
704 |
– |
pool = w.pool; |
705 |
– |
} |
706 |
– |
else |
707 |
– |
pool = null; |
708 |
– |
/* |
709 |
– |
* Timed wait loop intermixes cases for FJ (pool != null) and |
710 |
– |
* non FJ threads. For FJ, decrement pool count but don't try |
711 |
– |
* for replacement; increment count on completion. For non-FJ, |
712 |
– |
* deal with interrupts. This is messy, but a little less so |
713 |
– |
* than is splitting the FJ and nonFJ cases. |
714 |
– |
*/ |
715 |
– |
boolean interrupted = false; |
716 |
– |
boolean dec = false; // true if pool count decremented |
723 |
|
long nanos = unit.toNanos(timeout); |
724 |
< |
for (;;) { |
725 |
< |
if (pool == null && Thread.interrupted()) { |
726 |
< |
interrupted = true; |
727 |
< |
break; |
724 |
> |
if (status >= 0) { |
725 |
> |
Thread t = Thread.currentThread(); |
726 |
> |
if (t instanceof ForkJoinWorkerThread) { |
727 |
> |
ForkJoinWorkerThread w = (ForkJoinWorkerThread) t; |
728 |
> |
boolean completed = false; // timed variant of quietlyJoin |
729 |
> |
if (w.unpushTask(this)) { |
730 |
> |
try { |
731 |
> |
completed = exec(); |
732 |
> |
} catch (Throwable rex) { |
733 |
> |
setExceptionalCompletion(rex); |
734 |
> |
} |
735 |
> |
} |
736 |
> |
if (completed) |
737 |
> |
setCompletion(NORMAL); |
738 |
> |
else if (status >= 0) |
739 |
> |
w.joinTask(this, true, nanos); |
740 |
|
} |
741 |
< |
int s = status; |
742 |
< |
if (s < 0) |
743 |
< |
break; |
726 |
< |
if (UNSAFE.compareAndSwapInt(this, statusOffset, s, SIGNAL)) { |
741 |
> |
else if (Thread.interrupted()) |
742 |
> |
throw new InterruptedException(); |
743 |
> |
else { |
744 |
|
long startTime = System.nanoTime(); |
745 |
< |
long nt; // wait time |
746 |
< |
while (status >= 0 && |
745 |
> |
int s; long nt; |
746 |
> |
while ((s = status) >= 0 && |
747 |
|
(nt = nanos - (System.nanoTime() - startTime)) > 0) { |
748 |
< |
if (pool != null && !dec) |
749 |
< |
dec = pool.tryDecrementRunningCount(); |
733 |
< |
else { |
748 |
> |
if (UNSAFE.compareAndSwapInt(this, statusOffset, s, |
749 |
> |
SIGNAL)) { |
750 |
|
long ms = nt / 1000000; |
751 |
|
int ns = (int) (nt % 1000000); |
752 |
< |
try { |
753 |
< |
synchronized (this) { |
754 |
< |
if (status >= 0) |
739 |
< |
wait(ms, ns); |
740 |
< |
} |
741 |
< |
} catch (InterruptedException ie) { |
742 |
< |
if (pool != null) |
743 |
< |
cancelIfTerminating(); |
744 |
< |
else { |
745 |
< |
interrupted = true; |
746 |
< |
break; |
747 |
< |
} |
752 |
> |
synchronized (this) { |
753 |
> |
if (status >= 0) |
754 |
> |
wait(ms, ns); // exit on IE throw |
755 |
|
} |
756 |
|
} |
757 |
|
} |
751 |
– |
break; |
758 |
|
} |
759 |
|
} |
754 |
– |
if (pool != null && dec) |
755 |
– |
pool.incrementRunningCount(); |
756 |
– |
if (interrupted) |
757 |
– |
throw new InterruptedException(); |
760 |
|
int es = status; |
761 |
|
if (es != NORMAL) { |
762 |
|
Throwable ex; |
793 |
|
return; |
794 |
|
} |
795 |
|
} |
796 |
< |
w.joinTask(this); |
796 |
> |
w.joinTask(this, false, 0L); |
797 |
|
} |
798 |
|
} |
799 |
|
else |
829 |
|
* processed. |
830 |
|
* |
831 |
|
* <p>This method may be invoked only from within {@code |
832 |
< |
* ForkJoinTask} computations (as may be determined using method |
832 |
> |
* ForkJoinPool} computations (as may be determined using method |
833 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
834 |
|
* result in exceptions or errors, possibly including {@code |
835 |
|
* ClassCastException}. |
848 |
|
* under any other usage conditions are not guaranteed. |
849 |
|
* This method may be useful when executing |
850 |
|
* pre-constructed trees of subtasks in loops. |
851 |
+ |
* |
852 |
+ |
* <p>Upon completion of this method, {@code isDone()} reports |
853 |
+ |
* {@code false}, and {@code getException()} reports {@code |
854 |
+ |
* null}. However, the value returned by {@code getRawResult} is |
855 |
+ |
* unaffected. To clear this value, you can invoke {@code |
856 |
+ |
* setRawResult(null)}. |
857 |
|
*/ |
858 |
|
public void reinitialize() { |
859 |
|
if (status == EXCEPTIONAL) |
894 |
|
* were not, stolen. |
895 |
|
* |
896 |
|
* <p>This method may be invoked only from within {@code |
897 |
< |
* ForkJoinTask} computations (as may be determined using method |
897 |
> |
* ForkJoinPool} computations (as may be determined using method |
898 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
899 |
|
* result in exceptions or errors, possibly including {@code |
900 |
|
* ClassCastException}. |
913 |
|
* fork other tasks. |
914 |
|
* |
915 |
|
* <p>This method may be invoked only from within {@code |
916 |
< |
* ForkJoinTask} computations (as may be determined using method |
916 |
> |
* ForkJoinPool} computations (as may be determined using method |
917 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
918 |
|
* result in exceptions or errors, possibly including {@code |
919 |
|
* ClassCastException}. |
936 |
|
* exceeded. |
937 |
|
* |
938 |
|
* <p>This method may be invoked only from within {@code |
939 |
< |
* ForkJoinTask} computations (as may be determined using method |
939 |
> |
* ForkJoinPool} computations (as may be determined using method |
940 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
941 |
|
* result in exceptions or errors, possibly including {@code |
942 |
|
* ClassCastException}. |
994 |
|
* otherwise. |
995 |
|
* |
996 |
|
* <p>This method may be invoked only from within {@code |
997 |
< |
* ForkJoinTask} computations (as may be determined using method |
997 |
> |
* ForkJoinPool} computations (as may be determined using method |
998 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
999 |
|
* result in exceptions or errors, possibly including {@code |
1000 |
|
* ClassCastException}. |
1013 |
|
* be useful otherwise. |
1014 |
|
* |
1015 |
|
* <p>This method may be invoked only from within {@code |
1016 |
< |
* ForkJoinTask} computations (as may be determined using method |
1016 |
> |
* ForkJoinPool} computations (as may be determined using method |
1017 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
1018 |
|
* result in exceptions or errors, possibly including {@code |
1019 |
|
* ClassCastException}. |
1036 |
|
* otherwise. |
1037 |
|
* |
1038 |
|
* <p>This method may be invoked only from within {@code |
1039 |
< |
* ForkJoinTask} computations (as may be determined using method |
1039 |
> |
* ForkJoinPool} computations (as may be determined using method |
1040 |
|
* {@link #inForkJoinPool}). Attempts to invoke in other contexts |
1041 |
|
* result in exceptions or errors, possibly including {@code |
1042 |
|
* ClassCastException}. |