ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/FutureTask.java
Revision: 1.47
Committed: Thu Sep 8 00:04:00 2005 UTC (18 years, 8 months ago) by dl
Branch: MAIN
Changes since 1.46: +0 -4 lines
Log Message:
Edit pass for happens-before descriptions

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