ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java
Revision: 1.59
Committed: Tue Mar 15 19:47:03 2011 UTC (13 years, 2 months ago) by jsr166
Branch: MAIN
CVS Tags: release-1_7_0
Changes since 1.58: +1 -1 lines
Log Message:
Update Creative Commons license URL in legal notices

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