ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java
Revision: 1.45
Committed: Fri Sep 2 01:03:08 2005 UTC (18 years, 9 months ago) by brian
Branch: MAIN
Changes since 1.44: +5 -0 lines
Log Message:
Happens-before markup

File Contents

# User Rev Content
1 tim 1.1 /*
2 dl 1.2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 dl 1.23 * Expert Group and released to the public domain, as explained at
4     * http://creativecommons.org/licenses/publicdomain
5 tim 1.1 */
6    
7     package java.util.concurrent;
8 jsr166 1.43 import java.util.concurrent.*; // for javadoc (till 6280605 is fixed)
9 dl 1.13 import java.util.concurrent.locks.*;
10    
11 tim 1.1 /**
12 dl 1.8 * A cancellable asynchronous computation. This class provides a base
13     * implementation of {@link Future}, with methods to start and cancel
14     * a computation, query to see if the computation is complete, and
15 dl 1.4 * retrieve the result of the computation. The result can only be
16     * retrieved when the computation has completed; the <tt>get</tt>
17     * method will block if the computation has not yet completed. Once
18 dl 1.8 * the computation has completed, the computation cannot be restarted
19     * or cancelled.
20 tim 1.1 *
21 dl 1.8 * <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.
25 tim 1.1 *
26 dl 1.14 * <p>In addition to serving as a standalone class, this class provides
27     * <tt>protected</tt> functionality that may be useful when creating
28     * customized task classes.
29     *
30 brian 1.45 * <p> Memory visibility effects: State changes to the resulting value
31     * or exception <a
32     * href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
33     * actions following a call to <tt>get()</tt>.
34     *
35 tim 1.1 * @since 1.5
36 dl 1.4 * @author Doug Lea
37 dl 1.12 * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
38 tim 1.1 */
39 peierls 1.39 public class FutureTask<V> implements RunnableFuture<V> {
40 dl 1.24 /** Synchronization control for FutureTask */
41     private final Sync sync;
42 dl 1.11
43 tim 1.1 /**
44 dl 1.31 * Creates a <tt>FutureTask</tt> that will upon running, execute the
45 tim 1.1 * given <tt>Callable</tt>.
46     *
47     * @param callable the callable task
48 dl 1.9 * @throws NullPointerException if callable is null
49 tim 1.1 */
50     public FutureTask(Callable<V> callable) {
51 dl 1.9 if (callable == null)
52     throw new NullPointerException();
53 dl 1.24 sync = new Sync(callable);
54 tim 1.1 }
55    
56     /**
57 dl 1.31 * Creates a <tt>FutureTask</tt> that will upon running, execute the
58 tim 1.1 * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
59     * given result on successful completion.
60     *
61     * @param runnable the runnable task
62     * @param result the result to return on successful completion. If
63 dl 1.9 * you don't need a particular result, consider using
64 dl 1.16 * constructions of the form:
65     * <tt>Future&lt;?&gt; f = new FutureTask&lt;Object&gt;(runnable, null)</tt>
66 dl 1.9 * @throws NullPointerException if runnable is null
67 tim 1.1 */
68 dl 1.15 public FutureTask(Runnable runnable, V result) {
69 dl 1.24 sync = new Sync(Executors.callable(runnable, result));
70 dl 1.20 }
71    
72     public boolean isCancelled() {
73 dl 1.27 return sync.innerIsCancelled();
74 dl 1.20 }
75 jsr166 1.35
76 dl 1.20 public boolean isDone() {
77 dl 1.27 return sync.innerIsDone();
78 dl 1.13 }
79    
80     public boolean cancel(boolean mayInterruptIfRunning) {
81 dl 1.27 return sync.innerCancel(mayInterruptIfRunning);
82 dl 1.13 }
83 jsr166 1.35
84 jsr166 1.43 /**
85     * @throws CancellationException {@inheritDoc}
86     */
87 dl 1.2 public V get() throws InterruptedException, ExecutionException {
88 dl 1.27 return sync.innerGet();
89 tim 1.1 }
90    
91 jsr166 1.43 /**
92     * @throws CancellationException {@inheritDoc}
93     */
94 dl 1.2 public V get(long timeout, TimeUnit unit)
95 tim 1.1 throws InterruptedException, ExecutionException, TimeoutException {
96 dl 1.27 return sync.innerGet(unit.toNanos(timeout));
97 tim 1.1 }
98    
99     /**
100 dl 1.20 * Protected method invoked when this task transitions to state
101     * <tt>isDone</tt> (whether normally or via cancellation). The
102     * default implementation does nothing. Subclasses may override
103     * this method to invoke completion callbacks or perform
104     * bookkeeping. Note that you can query status inside the
105     * implementation of this method to determine whether this task
106     * has been cancelled.
107     */
108     protected void done() { }
109    
110     /**
111     * Sets the result of this Future to the given value unless
112 dl 1.29 * this future has already been set or has been cancelled.
113 dl 1.40 * This method is invoked internally by the <tt>run</tt> method
114     * upon successful completion of the computation.
115 tim 1.1 * @param v the value
116 jsr166 1.35 */
117 dl 1.2 protected void set(V v) {
118 dl 1.27 sync.innerSet(v);
119 tim 1.1 }
120    
121     /**
122 dl 1.13 * Causes this future to report an <tt>ExecutionException</tt>
123 dl 1.20 * with the given throwable as its cause, unless this Future has
124 dl 1.24 * already been set or has been cancelled.
125 dl 1.40 * This method is invoked internally by the <tt>run</tt> method
126     * upon failure of the computation.
127 jsr166 1.41 * @param t the cause of failure
128 jsr166 1.35 */
129 dl 1.2 protected void setException(Throwable t) {
130 dl 1.27 sync.innerSetException(t);
131 tim 1.1 }
132 jsr166 1.35
133 jsr166 1.44 // The following (duplicated) doc comment can be removed once
134     //
135     // 6270645: Javadoc comments should be inherited from most derived
136     // superinterface or superclass
137     // is fixed.
138     /**
139     * Sets this Future to the result of its computation
140     * unless it has been cancelled.
141     */
142 dl 1.24 public void run() {
143 dl 1.27 sync.innerRun();
144 dl 1.24 }
145    
146     /**
147 dl 1.30 * Executes the computation without setting its result, and then
148     * resets this Future to initial state, failing to do so if the
149 dl 1.24 * computation encounters an exception or is cancelled. This is
150     * designed for use with tasks that intrinsically execute more
151     * than once.
152     * @return true if successfully run and reset
153     */
154     protected boolean runAndReset() {
155 dl 1.27 return sync.innerRunAndReset();
156 dl 1.14 }
157 dl 1.3
158 dl 1.14 /**
159 dl 1.24 * Synchronization control for FutureTask. Note that this must be
160 dl 1.30 * a non-static inner class in order to invoke the protected
161 dl 1.24 * <tt>done</tt> method. For clarity, all inner class support
162 dl 1.27 * methods are same as outer, prefixed with "inner".
163 dl 1.24 *
164     * Uses AQS sync state to represent run status
165 dl 1.20 */
166 dl 1.24 private final class Sync extends AbstractQueuedSynchronizer {
167 dl 1.42 private static final long serialVersionUID = -7828117401763700385L;
168    
169 dl 1.24 /** State value representing that task is running */
170     private static final int RUNNING = 1;
171     /** State value representing that task ran */
172     private static final int RAN = 2;
173     /** State value representing that task was cancelled */
174     private static final int CANCELLED = 4;
175    
176     /** The underlying callable */
177     private final Callable<V> callable;
178     /** The result to return from get() */
179     private V result;
180     /** The exception to throw from get() */
181     private Throwable exception;
182    
183 jsr166 1.35 /**
184 dl 1.24 * The thread running task. When nulled after set/cancel, this
185     * indicates that the results are accessible. Must be
186 dl 1.32 * volatile, to ensure visibility upon completion.
187 dl 1.24 */
188     private volatile Thread runner;
189    
190     Sync(Callable<V> callable) {
191     this.callable = callable;
192     }
193    
194     private boolean ranOrCancelled(int state) {
195     return (state & (RAN | CANCELLED)) != 0;
196     }
197    
198     /**
199 dl 1.26 * Implements AQS base acquire to succeed if ran or cancelled
200 dl 1.24 */
201 dl 1.26 protected int tryAcquireShared(int ignore) {
202 dl 1.27 return innerIsDone()? 1 : -1;
203 dl 1.24 }
204    
205     /**
206     * Implements AQS base release to always signal after setting
207     * final done status by nulling runner thread.
208     */
209 dl 1.25 protected boolean tryReleaseShared(int ignore) {
210 dl 1.24 runner = null;
211 jsr166 1.35 return true;
212 dl 1.24 }
213    
214 dl 1.27 boolean innerIsCancelled() {
215 dl 1.24 return getState() == CANCELLED;
216     }
217 jsr166 1.35
218 dl 1.27 boolean innerIsDone() {
219 dl 1.24 return ranOrCancelled(getState()) && runner == null;
220     }
221    
222 dl 1.27 V innerGet() throws InterruptedException, ExecutionException {
223 dl 1.24 acquireSharedInterruptibly(0);
224     if (getState() == CANCELLED)
225     throw new CancellationException();
226     if (exception != null)
227     throw new ExecutionException(exception);
228     return result;
229     }
230    
231 dl 1.27 V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
232 dl 1.28 if (!tryAcquireSharedNanos(0, nanosTimeout))
233 jsr166 1.35 throw new TimeoutException();
234 dl 1.24 if (getState() == CANCELLED)
235     throw new CancellationException();
236     if (exception != null)
237     throw new ExecutionException(exception);
238     return result;
239     }
240    
241 dl 1.27 void innerSet(V v) {
242 jsr166 1.38 for (;;) {
243     int s = getState();
244     if (ranOrCancelled(s))
245     return;
246     if (compareAndSetState(s, RAN))
247     break;
248     }
249 dl 1.24 result = v;
250     releaseShared(0);
251     done();
252     }
253    
254 dl 1.27 void innerSetException(Throwable t) {
255 jsr166 1.38 for (;;) {
256     int s = getState();
257     if (ranOrCancelled(s))
258     return;
259     if (compareAndSetState(s, RAN))
260     break;
261     }
262 dl 1.24 exception = t;
263     result = null;
264     releaseShared(0);
265     done();
266     }
267    
268 dl 1.27 boolean innerCancel(boolean mayInterruptIfRunning) {
269 jsr166 1.38 for (;;) {
270     int s = getState();
271     if (ranOrCancelled(s))
272     return false;
273     if (compareAndSetState(s, CANCELLED))
274     break;
275     }
276 dl 1.24 if (mayInterruptIfRunning) {
277     Thread r = runner;
278     if (r != null)
279     r.interrupt();
280     }
281     releaseShared(0);
282     done();
283 dl 1.14 return true;
284     }
285    
286 dl 1.27 void innerRun() {
287 jsr166 1.35 if (!compareAndSetState(0, RUNNING))
288 dl 1.24 return;
289 dl 1.14 try {
290 dl 1.24 runner = Thread.currentThread();
291 dl 1.37 if (getState() == RUNNING) // recheck after setting thread
292 dl 1.36 innerSet(callable.call());
293     else
294 dl 1.37 releaseShared(0); // cancel
295 jsr166 1.34 } catch (Throwable ex) {
296 dl 1.27 innerSetException(ex);
297 jsr166 1.35 }
298 dl 1.14 }
299    
300 dl 1.27 boolean innerRunAndReset() {
301 jsr166 1.35 if (!compareAndSetState(0, RUNNING))
302 dl 1.24 return false;
303 dl 1.15 try {
304 dl 1.24 runner = Thread.currentThread();
305 dl 1.36 if (getState() == RUNNING)
306     callable.call(); // don't set result
307 dl 1.24 runner = null;
308     return compareAndSetState(RUNNING, 0);
309 jsr166 1.34 } catch (Throwable ex) {
310 dl 1.27 innerSetException(ex);
311 dl 1.24 return false;
312 jsr166 1.35 }
313 dl 1.14 }
314 dl 1.15 }
315     }