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

Comparing jsr166/src/jsr166y/ForkJoinTask.java (file contents):
Revision 1.24 by jsr166, Mon Jul 27 21:41:53 2009 UTC vs.
Revision 1.27 by dl, Sun Aug 2 11:54:31 2009 UTC

# Line 16 | Line 16 | import java.util.Map;
16   import java.util.WeakHashMap;
17  
18   /**
19 < * Abstract base class for tasks that run within a {@link
20 < * ForkJoinPool}.  A ForkJoinTask is a thread-like entity that is much
19 > * Abstract base class for tasks that run within a {@link ForkJoinPool}.
20 > * A {@code ForkJoinTask} is a thread-like entity that is much
21   * lighter weight than a normal thread.  Huge numbers of tasks and
22   * subtasks may be hosted by a small number of actual threads in a
23   * ForkJoinPool, at the price of some usage limitations.
# Line 76 | Line 76 | import java.util.WeakHashMap;
76   *
77   * <p> The ForkJoinTask class is not usually directly subclassed.
78   * Instead, you subclass one of the abstract classes that support a
79 < * particular style of fork/join processing.  Normally, a concrete
79 > * particular style of fork/join processing, typically {@link
80 > * RecursiveAction} for computations that do not return results, or
81 > * {@link RecursiveTask} for those that do.  Normally, a concrete
82   * ForkJoinTask subclass declares fields comprising its parameters,
83   * established in a constructor, and then defines a {@code compute}
84   * method that somehow uses the control methods supplied by this base
# Line 106 | Line 108 | import java.util.WeakHashMap;
108   * parallelism cannot improve throughput. If too small, then memory
109   * and internal task maintenance overhead may overwhelm processing.
110   *
111 + * <p>This class provides {@code adapt} methods for {@link
112 + * java.lang.Runnable} and {@link java.util.concurrent.Callable}, that
113 + * may be of use when mixing execution of ForkJoinTasks with other
114 + * kinds of tasks. When all tasks are of this form, consider using a
115 + * pool in {@link ForkJoinPool#setAsyncMode}.
116 + *
117   * <p>ForkJoinTasks are {@code Serializable}, which enables them
118   * to be used in extensions such as remote execution frameworks. It is
119   * in general sensible to serialize tasks only before or after, but
# Line 247 | Line 255 | public abstract class ForkJoinTask<V> im
255          synchronized (this) {
256              try {
257                  while (status >= 0) {
258 <                    long nt = nanos - System.nanoTime() - startTime;
258 >                    long nt = nanos - (System.nanoTime() - startTime);
259                      if (nt <= 0)
260                          break;
261                      wait(nt / 1000000, (int) (nt % 1000000));
# Line 531 | Line 539 | public abstract class ForkJoinTask<V> im
539      }
540  
541      /**
542 <     * Forks both tasks, returning when {@code isDone} holds for
543 <     * both of them or an exception is encountered. This method may be
542 >     * Forks the given tasks, returning when {@code isDone} holds for
543 >     * each task or an exception is encountered. This method may be
544       * invoked only from within ForkJoinTask computations (as may be
545       * determined using method {@link #inForkJoinPool}). Attempts to
546       * invoke in other contexts result in exceptions or errors,
547       * possibly including ClassCastException.
548       *
549 <     * @param t1 one task
550 <     * @param t2 the other task
551 <     * @throws NullPointerException if t1 or t2 are null
552 <     * @throws RuntimeException or Error if either task did so
549 >     * @param t1 the first task
550 >     * @param t2 the second task
551 >     * @throws NullPointerException if any task is null
552 >     * @throws RuntimeException or Error if a task did so
553       */
554      public static void invokeAll(ForkJoinTask<?>t1, ForkJoinTask<?> t2) {
555          t2.fork();
# Line 550 | Line 558 | public abstract class ForkJoinTask<V> im
558      }
559  
560      /**
561 <     * Forks the given tasks, returning when {@code isDone} holds
562 <     * for all of them. If any task encounters an exception, others
563 <     * may be cancelled.  This method may be invoked only from within
561 >     * Forks the given tasks, returning when {@code isDone} holds for
562 >     * each task or an exception is encountered. If any task
563 >     * encounters an exception, others may be, but are not guaranteed
564 >     * to be, cancelled.  This method may be invoked only from within
565       * ForkJoinTask computations (as may be determined using method
566       * {@link #inForkJoinPool}). Attempts to invoke in other contexts
567       * result in exceptions or errors, possibly including
568       * ClassCastException.
569       *
570 <     * @param tasks the array of tasks
570 >     * Overloadings of this method exist for the special cases
571 >     * of one to four arguments.
572 >     *
573 >     * @param tasks the tasks
574       * @throws NullPointerException if tasks or any element are null
575       * @throws RuntimeException or Error if any task did so
576       */
# Line 596 | Line 608 | public abstract class ForkJoinTask<V> im
608      }
609  
610      /**
611 <     * Forks all tasks in the collection, returning when
612 <     * {@code isDone} holds for all of them. If any task
613 <     * encounters an exception, others may be cancelled.  This method
614 <     * may be invoked only from within ForkJoinTask computations (as
615 <     * may be determined using method {@link
616 <     * #inForkJoinPool}). Attempts to invoke in other contexts result
617 <     * in exceptions or errors, possibly including ClassCastException.
611 >     * Forks all tasks in the collection, returning when {@code
612 >     * isDone} holds for each task or an exception is encountered. If
613 >     * any task encounters an exception, others may be, but are not
614 >     * guaranteed to be, cancelled.  This method may be invoked only
615 >     * from within ForkJoinTask computations (as may be determined
616 >     * using method {@link #inForkJoinPool}). Attempts to invoke in
617 >     * other contexts result in exceptions or errors, possibly
618 >     * including ClassCastException.
619       *
620       * @param tasks the collection of tasks
621       * @return the tasks argument, to simplify usage
# Line 732 | Line 745 | public abstract class ForkJoinTask<V> im
745       * {@code join} and related operations. This method may be used
746       * to induce exceptions in asynchronous tasks, or to force
747       * completion of tasks that would not otherwise complete.  Its use
748 <     * in other situations is likely to be wrong.  This method is
748 >     * in other situations is discouraged.  This method is
749       * overridable, but overridden versions must invoke {@code super}
750       * implementation to maintain guarantees.
751       *
# Line 752 | Line 765 | public abstract class ForkJoinTask<V> im
765       * operations. This method may be used to provide results for
766       * asynchronous tasks, or to provide alternative handling for
767       * tasks that would not otherwise complete normally. Its use in
768 <     * other situations is likely to be wrong. This method is
768 >     * other situations is discouraged. This method is
769       * overridable, but overridden versions must invoke {@code super}
770       * implementation to maintain guarantees.
771       *
# Line 777 | Line 790 | public abstract class ForkJoinTask<V> im
790  
791      public final V get(long timeout, TimeUnit unit)
792          throws InterruptedException, ExecutionException, TimeoutException {
793 +        long nanos = unit.toNanos(timeout);
794          ForkJoinWorkerThread w = getWorker();
795          if (w == null || status < 0 || !w.unpushTask(this) || !tryQuietlyInvoke())
796 <            awaitDone(w, unit.toNanos(timeout));
796 >            awaitDone(w, nanos);
797          return reportTimedFutureResult();
798      }
799  
# Line 851 | Line 865 | public abstract class ForkJoinTask<V> im
865       * Possibly executes tasks until the pool hosting the current task
866       * {@link ForkJoinPool#isQuiescent}. This method may be of use in
867       * designs in which many tasks are forked, but none are explicitly
868 <     * joined, instead executing them until all are processed.
868 >     * joined, instead executing them until all are processed.  This
869 >     * method may be invoked only from within ForkJoinTask
870 >     * computations (as may be determined using method {@link
871 >     * #inForkJoinPool}). Attempts to invoke in other contexts result
872 >     * in exceptions or errors, possibly including ClassCastException.
873       */
874      public static void helpQuiesce() {
875          ((ForkJoinWorkerThread) Thread.currentThread())
# Line 865 | Line 883 | public abstract class ForkJoinTask<V> im
883       * never been forked, or has been forked, then completed and all
884       * outstanding joins of this task have also completed. Effects
885       * under any other usage conditions are not guaranteed, and are
886 <     * almost surely wrong. This method may be useful when executing
886 >     * discouraged. This method may be useful when executing
887       * pre-constructed trees of subtasks in loops.
888       */
889      public void reinitialize() {
# Line 878 | Line 896 | public abstract class ForkJoinTask<V> im
896       * Returns the pool hosting the current task execution, or null
897       * if this task is executing outside of any ForkJoinPool.
898       *
899 +     * @see #inForkJoinPool
900       * @return the pool, or {@code null} if none
901       */
902      public static ForkJoinPool getPool() {
# Line 920 | Line 939 | public abstract class ForkJoinTask<V> im
939       * Returns an estimate of the number of tasks that have been
940       * forked by the current worker thread but not yet executed. This
941       * value may be useful for heuristic decisions about whether to
942 <     * fork other tasks.
943 <     *
942 >     * fork other tasks.  This method may be invoked only from within
943 >     * ForkJoinTask computations (as may be determined using method
944 >     * {@link #inForkJoinPool}). Attempts to invoke in other contexts
945 >     * result in exceptions or errors, possibly including
946 >     * ClassCastException.
947       * @return the number of tasks
948       */
949      public static int getQueuedTaskCount() {
# Line 937 | Line 959 | public abstract class ForkJoinTask<V> im
959       * usages of ForkJoinTasks, at steady state, each worker should
960       * aim to maintain a small constant surplus (for example, 3) of
961       * tasks, and to process computations locally if this threshold is
962 <     * exceeded.
963 <     *
962 >     * exceeded.  This method may be invoked only from within
963 >     * ForkJoinTask computations (as may be determined using method
964 >     * {@link #inForkJoinPool}). Attempts to invoke in other contexts
965 >     * result in exceptions or errors, possibly including
966 >     * ClassCastException.  *
967       * @return the surplus number of tasks, which may be negative
968       */
969      public static int getSurplusQueuedTaskCount() {
# Line 983 | Line 1008 | public abstract class ForkJoinTask<V> im
1008      protected abstract boolean exec();
1009  
1010      /**
1011 <     * Returns, but does not unschedule or execute, the task queued by
1012 <     * the current thread but not yet executed, if one is
1011 >     * Returns, but does not unschedule or execute, a task queued by
1012 >     * the current thread but not yet executed, if one is immediately
1013       * available. There is no guarantee that this task will actually
1014 <     * be polled or executed next.  This method is designed primarily
1015 <     * to support extensions, and is unlikely to be useful otherwise.
1016 <     * This method may be invoked only from within ForkJoinTask
1017 <     * computations (as may be determined using method {@link
1018 <     * #inForkJoinPool}). Attempts to invoke in other contexts result
1019 <     * in exceptions or errors, possibly including ClassCastException.
1014 >     * be polled or executed next. Conversely, this method may return
1015 >     * null even if a task exists but cannot be accessed without
1016 >     * contention with other threads.  This method is designed
1017 >     * primarily to support extensions, and is unlikely to be useful
1018 >     * otherwise.  This method may be invoked only from within
1019 >     * ForkJoinTask computations (as may be determined using method
1020 >     * {@link #inForkJoinPool}). Attempts to invoke in other contexts
1021 >     * result in exceptions or errors, possibly including
1022 >     * ClassCastException.
1023       *
1024       * @return the next task, or {@code null} if none are available
1025       */
# Line 1038 | Line 1066 | public abstract class ForkJoinTask<V> im
1066              .pollTask();
1067      }
1068  
1069 <    // adaptors
1069 >    /**
1070 >     * Adaptor for Runnables. This implements RunnableFuture
1071 >     * to be compliant with AbstractExecutorService constraints
1072 >     * when used in ForkJoinPool.
1073 >     */
1074 >    static final class AdaptedRunnable<T> extends ForkJoinTask<T>
1075 >        implements RunnableFuture<T> {
1076 >        final Runnable runnable;
1077 >        final T resultOnCompletion;
1078 >        T result;
1079 >        AdaptedRunnable(Runnable runnable, T result) {
1080 >            if (runnable == null) throw new NullPointerException();
1081 >            this.runnable = runnable;
1082 >            this.resultOnCompletion = result;
1083 >        }
1084 >        public T getRawResult() { return result; }
1085 >        public void setRawResult(T v) { result = v; }
1086 >        public boolean exec() {
1087 >            runnable.run();
1088 >            result = resultOnCompletion;
1089 >            return true;
1090 >        }
1091 >        public void run() { invoke(); }
1092 >        private static final long serialVersionUID = 5232453952276885070L;
1093 >    }
1094 >
1095 >    /**
1096 >     * Adaptor for Callables
1097 >     */
1098 >    static final class AdaptedCallable<T> extends ForkJoinTask<T>
1099 >        implements RunnableFuture<T> {
1100 >        final Callable<? extends T> callable;
1101 >        T result;
1102 >        AdaptedCallable(Callable<? extends T> callable) {
1103 >            if (callable == null) throw new NullPointerException();
1104 >            this.callable = callable;
1105 >        }
1106 >        public T getRawResult() { return result; }
1107 >        public void setRawResult(T v) { result = v; }
1108 >        public boolean exec() {
1109 >            try {
1110 >                result = callable.call();
1111 >                return true;
1112 >            } catch (Error err) {
1113 >                throw err;
1114 >            } catch (RuntimeException rex) {
1115 >                throw rex;
1116 >            } catch (Exception ex) {
1117 >                throw new RuntimeException(ex);
1118 >            }
1119 >        }
1120 >        public void run() { invoke(); }
1121 >        private static final long serialVersionUID = 2838392045355241008L;
1122 >    }
1123  
1124      /**
1125       * Returns a new ForkJoinTask that performs the {@code run}
# Line 1048 | Line 1129 | public abstract class ForkJoinTask<V> im
1129       * @param runnable the runnable action
1130       * @return the task
1131       */
1132 <    public static ForkJoinTask<Void> adapt(Runnable runnable) {
1133 <        return new ForkJoinPool.AdaptedRunnable<Void>(runnable, null);
1132 >    public static ForkJoinTask<?> adapt(Runnable runnable) {
1133 >        return new AdaptedRunnable<Void>(runnable, null);
1134      }
1135  
1136      /**
# Line 1062 | Line 1143 | public abstract class ForkJoinTask<V> im
1143       * @return the task
1144       */
1145      public static <T> ForkJoinTask<T> adapt(Runnable runnable, T result) {
1146 <        return new ForkJoinPool.AdaptedRunnable<T>(runnable, result);
1146 >        return new AdaptedRunnable<T>(runnable, result);
1147      }
1148  
1149      /**
# Line 1074 | Line 1155 | public abstract class ForkJoinTask<V> im
1155       * @param callable the callable action
1156       * @return the task
1157       */
1158 <    public static <T> ForkJoinTask<T> adapt(Callable<T> callable) {
1159 <        return new ForkJoinPool.AdaptedCallable<T>(callable);
1158 >    public static <T> ForkJoinTask<T> adapt(Callable<? extends T> callable) {
1159 >        return new AdaptedCallable<T>(callable);
1160      }
1161  
1162      // Serialization support

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines