ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/ForkJoinTask.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/ForkJoinTask.java (file contents):
Revision 1.7 by jsr166, Tue Aug 4 01:23:41 2009 UTC vs.
Revision 1.8 by jsr166, Tue Aug 4 20:41:40 2009 UTC

# Line 66 | Line 66 | import java.util.WeakHashMap;
66   * execute other tasks while awaiting joins, which is sometimes more
67   * efficient but only applies when all subtasks are known to be
68   * strictly tree-structured. Method {@link #invoke} is semantically
69 < * equivalent to {@code fork(); join()} but always attempts to
70 < * begin execution in the current thread. The "<em>quiet</em>" forms
71 < * of these methods do not extract results or report exceptions. These
69 > * equivalent to {@code fork(); join()} but always attempts to begin
70 > * execution in the current thread. The "<em>quiet</em>" forms of
71 > * these methods do not extract results or report exceptions. These
72   * may be useful when a set of tasks are being executed, and you need
73   * to delay processing of results or exceptions until all complete.
74   * Method {@code invokeAll} (available in multiple versions)
75   * performs the most common form of parallel invocation: forking a set
76   * of tasks and joining them all.
77   *
78 + * <p>The execution status of tasks may be queried at several levels
79 + * of detail: {@link #isDone} is true if a task completed in any way
80 + * (including the case where a task was cancelled without executing);
81 + * {@link #isCancelled} is true if completion was due to cancellation;
82 + * {@link #isCompletedNormally} is true if a task completed without
83 + * cancellation or encountering an exception; {@link
84 + * #isCompletedExceptionally} is true if if the task encountered an
85 + * exception (in which case {@link #getException} returns the
86 + * exception); {@link #isCancelled} is true if the task was cancelled
87 + * (in which case {@link #getException} returns a {@link
88 + * java.util.concurrent.CancellationException}); and {@link
89 + * #isCompletedAbnormally} is true if a task was either cancelled or
90 + * encountered an exception.
91 + *
92   * <p>The ForkJoinTask class is not usually directly subclassed.
93   * Instead, you subclass one of the abstract classes that support a
94   * particular style of fork/join processing, typically {@link
# Line 109 | Line 123 | import java.util.WeakHashMap;
123   * improve throughput. If too small, then memory and internal task
124   * maintenance overhead may overwhelm processing.
125   *
126 < * <p>This class provides {@code adapt} methods for {@link
127 < * java.lang.Runnable} and {@link java.util.concurrent.Callable}, that
128 < * may be of use when mixing execution of ForkJoinTasks with other
129 < * kinds of tasks. When all tasks are of this form, consider using a
130 < * pool in {@link ForkJoinPool#setAsyncMode}.
126 > * <p>This class provides {@code adapt} methods for {@link Runnable}
127 > * and {@link Callable}, that may be of use when mixing execution of
128 > * {@code ForkJoinTasks} with other kinds of tasks. When all tasks
129 > * are of this form, consider using a pool in
130 > * {@linkplain ForkJoinPool#setAsyncMode async mode}.
131   *
132   * <p>ForkJoinTasks are {@code Serializable}, which enables them to be
133   * used in extensions such as remote execution frameworks. It is
# Line 379 | Line 393 | public abstract class ForkJoinTask<V> im
393       * Only call when {@code isDone} known to be true.
394       */
395      private V reportFutureResult()
396 <        throws ExecutionException, InterruptedException {
396 >        throws InterruptedException, ExecutionException {
397 >        if (Thread.interrupted())
398 >            throw new InterruptedException();
399          int s = status & COMPLETION_MASK;
400          if (s < NORMAL) {
401              Throwable ex;
# Line 387 | Line 403 | public abstract class ForkJoinTask<V> im
403                  throw new CancellationException();
404              if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null)
405                  throw new ExecutionException(ex);
390            if (Thread.interrupted())
391                throw new InterruptedException();
406          }
407          return getRawResult();
408      }
# Line 399 | Line 413 | public abstract class ForkJoinTask<V> im
413       */
414      private V reportTimedFutureResult()
415          throws InterruptedException, ExecutionException, TimeoutException {
416 +        if (Thread.interrupted())
417 +            throw new InterruptedException();
418          Throwable ex;
419          int s = status & COMPLETION_MASK;
420          if (s == NORMAL)
421              return getRawResult();
422 <        if (s == CANCELLED)
422 >        else if (s == CANCELLED)
423              throw new CancellationException();
424 <        if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null)
424 >        else if (s == EXCEPTIONAL && (ex = exceptionMap.get(this)) != null)
425              throw new ExecutionException(ex);
426 <        if (Thread.interrupted())
427 <            throw new InterruptedException();
412 <        throw new TimeoutException();
426 >        else
427 >            throw new TimeoutException();
428      }
429  
430      // internal execution methods
# Line 527 | Line 542 | public abstract class ForkJoinTask<V> im
542  
543      /**
544       * Commences performing this task, awaits its completion if
545 <     * necessary, and return its result.
545 >     * necessary, and return its result, or throws an (unchecked)
546 >     * exception if the underlying computation did so.
547       *
532     * @throws Throwable (a RuntimeException, Error, or unchecked
533     * exception) if the underlying computation did so
548       * @return the computed result
549       */
550      public final V invoke() {
# Line 541 | Line 555 | public abstract class ForkJoinTask<V> im
555      }
556  
557      /**
558 <     * Forks the given tasks, returning when {@code isDone} holds
559 <     * for each task or an exception is encountered.
558 >     * Forks the given tasks, returning when {@code isDone} holds for
559 >     * each task or an (unchecked) exception is encountered, in which
560 >     * case the exception is rethrown.  If more than one task
561 >     * encounters an exception, then this method throws any one of
562 >     * these exceptions.  The individual status of each task may be
563 >     * checked using {@link #getException()} and related methods.
564       *
565       * <p>This method may be invoked only from within {@code
566       * ForkJoinTask} computations (as may be determined using method
# Line 553 | Line 571 | public abstract class ForkJoinTask<V> im
571       * @param t1 the first task
572       * @param t2 the second task
573       * @throws NullPointerException if any task is null
556     * @throws RuntimeException or Error if a task did so
574       */
575      public static void invokeAll(ForkJoinTask<?> t1, ForkJoinTask<?> t2) {
576          t2.fork();
# Line 563 | Line 580 | public abstract class ForkJoinTask<V> im
580  
581      /**
582       * Forks the given tasks, returning when {@code isDone} holds for
583 <     * each task or an exception is encountered. If any task
584 <     * encounters an exception, others may be, but are not guaranteed
585 <     * to be, cancelled.
583 >     * each task or an (unchecked) exception is encountered, in which
584 >     * case the exception is rethrown. If any task encounters an
585 >     * exception, others may be, but are not guaranteed to be,
586 >     * cancelled.  If more than one task encounters an exception, then
587 >     * this method throws any one of these exceptions.  The individual
588 >     * status of each task may be checked using {@link #getException()}
589 >     * and related methods.
590       *
591       * <p>This method may be invoked only from within {@code
592       * ForkJoinTask} computations (as may be determined using method
# Line 574 | Line 595 | public abstract class ForkJoinTask<V> im
595       * ClassCastException}.
596       *
597       * @param tasks the tasks
598 <     * @throws NullPointerException if tasks or any element are null
578 <     * @throws RuntimeException or Error if any task did so
598 >     * @throws NullPointerException if any task is null
599       */
600      public static void invokeAll(ForkJoinTask<?>... tasks) {
601          Throwable ex = null;
# Line 612 | Line 632 | public abstract class ForkJoinTask<V> im
632  
633      /**
634       * Forks all tasks in the specified collection, returning when
635 <     * {@code isDone} holds for each task or an exception is
636 <     * encountered.  If any task encounters an exception, others may
637 <     * be, but are not guaranteed to be, cancelled. The behavior of
638 <     * this operation is undefined if the specified collection is
639 <     * modified while the operation is in progress.
635 >     * {@code isDone} holds for each task or an (unchecked) exception
636 >     * is encountered.  If any task encounters an exception, others
637 >     * may be, but are not guaranteed to be, cancelled.  If more than
638 >     * one task encounters an exception, then this method throws any
639 >     * one of these exceptions.  The individual status of each task
640 >     * may be checked using {@link #getException()} and related
641 >     * methods.  The behavior of this operation is undefined if the
642 >     * specified collection is modified while the operation is in
643 >     * progress.
644       *
645       * <p>This method may be invoked only from within {@code
646       * ForkJoinTask} computations (as may be determined using method
# Line 627 | Line 651 | public abstract class ForkJoinTask<V> im
651       * @param tasks the collection of tasks
652       * @return the tasks argument, to simplify usage
653       * @throws NullPointerException if tasks or any element are null
630     * @throws RuntimeException or Error if any task did so
654       */
655      public static <T extends ForkJoinTask<?>> Collection<T> invokeAll(Collection<T> tasks) {
656          if (!(tasks instanceof RandomAccess) || !(tasks instanceof List<?>)) {
# Line 671 | Line 694 | public abstract class ForkJoinTask<V> im
694      }
695  
696      /**
674     * Returns {@code true} if the computation performed by this task
675     * has completed (or has been cancelled).
676     *
677     * @return {@code true} if this computation has completed
678     */
679    public final boolean isDone() {
680        return status < 0;
681    }
682
683    /**
684     * Returns {@code true} if this task was cancelled.
685     *
686     * @return {@code true} if this task was cancelled
687     */
688    public final boolean isCancelled() {
689        return (status & COMPLETION_MASK) == CANCELLED;
690    }
691
692    /**
697       * Attempts to cancel execution of this task. This attempt will
698       * fail if the task has already completed, has already been
699       * cancelled, or could not be cancelled for some other reason. If
# Line 719 | Line 723 | public abstract class ForkJoinTask<V> im
723      }
724  
725      /**
726 +     * Returns {@code true} if the computation performed by this task
727 +     * has completed (or has been cancelled).
728 +     *
729 +     * @return {@code true} if this computation has completed
730 +     */
731 +    public final boolean isDone() {
732 +        return status < 0;
733 +    }
734 +
735 +    /**
736 +     * Returns {@code true} if this task was cancelled.
737 +     *
738 +     * @return {@code true} if this task was cancelled
739 +     */
740 +    public final boolean isCancelled() {
741 +        return (status & COMPLETION_MASK) == CANCELLED;
742 +    }
743 +
744 +    /**
745       * Returns {@code true} if this task threw an exception or was cancelled.
746       *
747       * @return {@code true} if this task threw an exception or was cancelled
# Line 728 | Line 751 | public abstract class ForkJoinTask<V> im
751      }
752  
753      /**
754 +     * Returns {@code true} if this task completed without throwing an
755 +     * exception and was not cancelled.
756 +     *
757 +     * @return {@code true} if this task completed without throwing an
758 +     * exception and was not cancelled
759 +     */
760 +    public final boolean isCompletedNormally() {
761 +        return (status & COMPLETION_MASK) == NORMAL;
762 +    }
763 +
764 +    /**
765 +     * Returns {@code true} if this task threw an exception.
766 +     *
767 +     * @return {@code true} if this task threw an exception
768 +     */
769 +    public final boolean isCompletedExceptionally() {
770 +        return (status & COMPLETION_MASK) == EXCEPTIONAL;
771 +    }
772 +
773 +    /**
774       * Returns the exception thrown by the base computation, or a
775       * {@code CancellationException} if cancelled, or {@code null} if
776       * none or if the method has not yet completed.
# Line 736 | Line 779 | public abstract class ForkJoinTask<V> im
779       */
780      public final Throwable getException() {
781          int s = status & COMPLETION_MASK;
782 <        if (s >= NORMAL)
783 <            return null;
784 <        if (s == CANCELLED)
742 <            return new CancellationException();
743 <        return exceptionMap.get(this);
782 >        return ((s >= NORMAL)    ? null :
783 >                (s == CANCELLED) ? new CancellationException() :
784 >                exceptionMap.get(this));
785      }
786  
787      /**
# Line 1020 | Line 1061 | public abstract class ForkJoinTask<V> im
1061       * called otherwise. The return value controls whether this task
1062       * is considered to be done normally. It may return false in
1063       * asynchronous actions that require explicit invocations of
1064 <     * {@link #complete} to become joinable. It may throw exceptions
1065 <     * to indicate abnormal exit.
1064 >     * {@link #complete} to become joinable. It may also throw an
1065 >     * (unchecked) exception to indicate abnormal exit.
1066       *
1067       * @return {@code true} if completed normally
1027     * @throws Error or RuntimeException if encountered during computation
1068       */
1069      protected abstract boolean exec();
1070  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines