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

Comparing jsr166/src/main/java/util/concurrent/FutureTask.java (file contents):
Revision 1.63 by jsr166, Fri Jun 17 18:53:13 2011 UTC vs.
Revision 1.64 by jsr166, Fri Jun 17 20:46:43 2011 UTC

# Line 12 | Line 12 | import java.util.concurrent.locks.LockSu
12   * implementation of {@link Future}, with methods to start and cancel
13   * a computation, query to see if the computation is complete, and
14   * retrieve the result of the computation.  The result can only be
15 < * retrieved when the computation has completed; the <tt>get</tt>
16 < * method will block if the computation has not yet completed.  Once
15 > * retrieved when the computation has completed; the {@code get}
16 > * methods will block if the computation has not yet completed.  Once
17   * the computation has completed, the computation cannot be restarted
18 < * or cancelled.
18 > * or cancelled (unless the computation is invoked using
19 > * {@link #runAndReset}).
20   *
21 < * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or
22 < * {@link java.lang.Runnable} object.  Because <tt>FutureTask</tt>
23 < * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be
24 < * submitted to an {@link Executor} for execution.
21 > * <p>A {@code FutureTask} can be used to wrap a {@link Callable} or
22 > * {@link Runnable} object.  Because {@code FutureTask} implements
23 > * {@code Runnable}, a {@code FutureTask} can be submitted to an
24 > * {@link Executor} for execution.
25   *
26   * <p>In addition to serving as a standalone class, this class provides
27 < * <tt>protected</tt> functionality that may be useful when creating
27 > * {@code protected} functionality that may be useful when creating
28   * customized task classes.
29   *
30   * @since 1.5
31   * @author Doug Lea
32 < * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
32 > * @param <V> The result type returned by this FutureTask's {@code get} methods
33   */
34   public class FutureTask<V> implements RunnableFuture<V> {
35      /*
# Line 48 | Line 49 | public class FutureTask<V> implements Ru
49       * transitions to NORMAL, EXCEPTIONAL, or CANCELLED (only) in
50       * method setCompletion. During setCompletion, state may take on
51       * transient values of COMPLETING (while outcome is being set) or
52 <     * INTERRUPTING (while interrupting the runner). State values
52 >     * INTERRUPTING (while interrupting the runner).  State values
53       * are ordered and set to powers of two to simplify checks.
54       */
55      private volatile int state;
# Line 58 | Line 59 | public class FutureTask<V> implements Ru
59      private static final int EXCEPTIONAL  = 0x08;
60      private static final int CANCELLED    = 0x10;
61  
62 +    /** The underlying callable */
63 +    private final Callable<V> callable;
64      /** The result to return or exception to throw from get() */
65      private Object outcome; // non-volatile, protected by state reads/writes
66      /** The thread running the callable; CASed during run() */
67      private volatile Thread runner;
65    /** The underlying callable */
66    private final Callable<V> callable;
68      /** Treiber stack of waiting threads */
69      private volatile WaitNode waiters;
70  
71      /**
72       * Sets completion status, unless already completed.  If
73       * necessary, we first set state to COMPLETING or INTERRUPTING to
74 <     * establish precedence. This intentionally stalls (just via
74 >     * establish precedence.  This intentionally stalls (just via
75       * yields) in (uncommon) cases of concurrent calls during
76       * cancellation until state is set, to avoid surprising users
77       * during cancellation races.
78       *
79       * @param x the outcome
80       * @param mode the completion state value
81 <     * @return true if this call caused transtion from 0 to completed
81 >     * @return true if this call caused transition from 0 to completed
82       */
83      private boolean setCompletion(Object x, int mode) {
84          Thread r = runner;
# Line 86 | Line 87 | public class FutureTask<V> implements Ru
87          int next = ((mode == INTERRUPTING) ? // set up transient states
88                      (r != null) ? INTERRUPTING : CANCELLED :
89                      (x != null) ? COMPLETING : mode);
90 <        for (int s;;) {
91 <            if ((s = state) == 0) {
90 >        for (;;) {
91 >            int s = state;
92 >            if (s == 0) {
93                  if (UNSAFE.compareAndSwapInt(this, stateOffset, 0, next)) {
94                      if (next == INTERRUPTING) {
95                          Thread t = runner; // recheck
# Line 106 | Line 108 | public class FutureTask<V> implements Ru
108                  }
109              }
110              else if (s == INTERRUPTING)
111 <                Thread.yield(); // wait out cancellation
111 >                Thread.yield(); // wait out pending cancellation interrupt
112              else
113                  return false;
114          }
115      }
116  
117      /**
118 <     * Returns result or throws exception for completed task
118 >     * Returns result or throws exception for completed task.
119 >     *
120       * @param s completed state value
121       */
122      private V report(int s) throws ExecutionException {
# Line 126 | Line 129 | public class FutureTask<V> implements Ru
129      }
130  
131      /**
132 <     * Creates a <tt>FutureTask</tt> that will, upon running, execute the
133 <     * given <tt>Callable</tt>.
132 >     * Creates a {@code FutureTask} that will, upon running, execute the
133 >     * given {@code Callable}.
134       *
135       * @param  callable the callable task
136       * @throws NullPointerException if callable is null
# Line 139 | Line 142 | public class FutureTask<V> implements Ru
142      }
143  
144      /**
145 <     * Creates a <tt>FutureTask</tt> that will, upon running, execute the
146 <     * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
145 >     * Creates a {@code FutureTask} that will, upon running, execute the
146 >     * given {@code Runnable}, and arrange that {@code get} will return the
147       * given result on successful completion.
148       *
149       * @param runnable the runnable task
# Line 172 | Line 175 | public class FutureTask<V> implements Ru
175       * @throws CancellationException {@inheritDoc}
176       */
177      public V get() throws InterruptedException, ExecutionException {
178 <        int s;
179 <        return report((s = state) > COMPLETING ? s : awaitDone(false, 0L));
178 >        int s = state;
179 >        if (s <= COMPLETING)
180 >            s = awaitDone(false, 0L);
181 >        return report(s);
182      }
183  
184      /**
# Line 181 | Line 186 | public class FutureTask<V> implements Ru
186       */
187      public V get(long timeout, TimeUnit unit)
188          throws InterruptedException, ExecutionException, TimeoutException {
189 <        int s;
190 <        long nanos = unit.toNanos(timeout);
191 <        if ((s = state) <= COMPLETING &&
187 <            (s = awaitDone(true, nanos)) <= COMPLETING)
189 >        int s = state;
190 >        if (s <= COMPLETING &&
191 >            (s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING)
192              throw new TimeoutException();
193          return report(s);
194      }
195  
196      /**
197       * Protected method invoked when this task transitions to state
198 <     * <tt>isDone</tt> (whether normally or via cancellation). The
198 >     * {@code isDone} (whether normally or via cancellation). The
199       * default implementation does nothing.  Subclasses may override
200       * this method to invoke completion callbacks or perform
201       * bookkeeping. Note that you can query status inside the
# Line 201 | Line 205 | public class FutureTask<V> implements Ru
205      protected void done() { }
206  
207      /**
208 <     * Sets the result of this Future to the given value unless
208 >     * Sets the result of this future to the given value unless
209       * this future has already been set or has been cancelled.
210 <     * This method is invoked internally by the <tt>run</tt> method
210 >     *
211 >     * <p>This method is invoked internally by the {@link #run} method
212       * upon successful completion of the computation.
213 +     *
214       * @param v the value
215       */
216      protected void set(V v) {
# Line 212 | Line 218 | public class FutureTask<V> implements Ru
218      }
219  
220      /**
221 <     * Causes this future to report an <tt>ExecutionException</tt>
222 <     * with the given throwable as its cause, unless this Future has
221 >     * Causes this future to report an {@link ExecutionException}
222 >     * with the given throwable as its cause, unless this future has
223       * already been set or has been cancelled.
224 <     * This method is invoked internally by the <tt>run</tt> method
224 >     *
225 >     * <p>This method is invoked internally by the {@link #run} method
226       * upon failure of the computation.
227 +     *
228       * @param t the cause of failure
229       */
230      protected void setException(Throwable t) {
# Line 240 | Line 248 | public class FutureTask<V> implements Ru
248  
249      /**
250       * Executes the computation without setting its result, and then
251 <     * resets this Future to initial state, failing to do so if the
251 >     * resets this future to initial state, failing to do so if the
252       * computation encounters an exception or is cancelled.  This is
253       * designed for use with tasks that intrinsically execute more
254       * than once.
255 +     *
256       * @return true if successfully run and reset
257       */
258      protected boolean runAndReset() {
# Line 264 | Line 273 | public class FutureTask<V> implements Ru
273                  return true;
274              if (s != INTERRUPTING)
275                  return false;
276 <            Thread.yield(); // wait out racing cancellation
276 >            Thread.yield(); // wait out pending cancellation interrupt
277          }
278      }
279  
280      /**
281       * Simple linked list nodes to record waiting threads in a Treiber
282 <     * stack. See other classes such as Phaser and SynchronousQueue
282 >     * stack.  See other classes such as Phaser and SynchronousQueue
283       * for more detailed explanation.
284       */
285      static final class WaitNode {
# Line 279 | Line 288 | public class FutureTask<V> implements Ru
288      }
289  
290      /**
291 <     * Removes and signals all waiting threads
291 >     * Removes and signals all waiting threads.
292       */
293      private void releaseAll() {
294          WaitNode q;
# Line 302 | Line 311 | public class FutureTask<V> implements Ru
311      }
312  
313      /**
314 <     * Awaits completion or aborts on interrupt of timeout
314 >     * Awaits completion or aborts on interrupt or timeout.
315 >     *
316       * @param timed true if use timed waits
317 <     * @param nanos time to wait if timed
317 >     * @param nanos time to wait, if timed
318       * @return state upon completion
319       */
320      private int awaitDone(boolean timed, long nanos)
# Line 312 | Line 322 | public class FutureTask<V> implements Ru
322          long last = timed ? System.nanoTime() : 0L;
323          WaitNode q = null;
324          boolean queued = false;
325 <        for (int s;;) {
325 >        for (;;) {
326              if (Thread.interrupted()) {
327                  removeWaiter(q);
328                  throw new InterruptedException();
329              }
330 <            else if ((s = state) > COMPLETING) {
330 >
331 >            int s = state;
332 >            if (s > COMPLETING) {
333                  if (q != null)
334                      q.thread = null;
335                  return s;
# Line 344 | Line 356 | public class FutureTask<V> implements Ru
356      }
357  
358      /**
359 <     * Try to unlink a timed-out or interrupted wait node to avoid
360 <     * accumulating garbage. Internal nodes are simply unspliced
359 >     * Tries to unlink a timed-out or interrupted wait node to avoid
360 >     * accumulating garbage.  Internal nodes are simply unspliced
361       * without CAS since it is harmless if they are traversed anyway
362       * by releasers or concurrent calls to removeWaiter.
363       */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines