2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * This code is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License version 2 only, as
6 * published by the Free Software Foundation. Oracle designates this
7 * particular file as subject to the "Classpath" exception as provided
8 * by Oracle in the LICENSE file that accompanied this code.
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
26 * This file is available under and governed by the GNU General Public
27 * License version 2 only, as published by the Free Software Foundation.
28 * However, the following notice accompanied the original version of this
31 * Written by Doug Lea with assistance from members of JCP JSR-166
32 * Expert Group and released to the public domain, as explained at
33 * http://creativecommons.org/publicdomain/zero/1.0/
36 package java.util.concurrent;
37 import java.util.concurrent.locks.*;
40 * A cancellable asynchronous computation. This class provides a base
41 * implementation of {@link Future}, with methods to start and cancel
42 * a computation, query to see if the computation is complete, and
43 * retrieve the result of the computation. The result can only be
44 * retrieved when the computation has completed; the <tt>get</tt>
45 * method will block if the computation has not yet completed. Once
46 * the computation has completed, the computation cannot be restarted
49 * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or
50 * {@link java.lang.Runnable} object. Because <tt>FutureTask</tt>
51 * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be
52 * submitted to an {@link Executor} for execution.
54 * <p>In addition to serving as a standalone class, this class provides
55 * <tt>protected</tt> functionality that may be useful when creating
56 * customized task classes.
60 * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
62 public class FutureTask<V> implements RunnableFuture<V> {
63 /** Synchronization control for FutureTask */
64 private final Sync sync;
67 * Creates a <tt>FutureTask</tt> that will, upon running, execute the
68 * given <tt>Callable</tt>.
70 * @param callable the callable task
71 * @throws NullPointerException if callable is null
73 public FutureTask(Callable<V> callable) {
75 throw new NullPointerException();
76 sync = new Sync(callable);
80 * Creates a <tt>FutureTask</tt> that will, upon running, execute the
81 * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
82 * given result on successful completion.
84 * @param runnable the runnable task
85 * @param result the result to return on successful completion. If
86 * you don't need a particular result, consider using
87 * constructions of the form:
88 * {@code Future<?> f = new FutureTask<Void>(runnable, null)}
89 * @throws NullPointerException if runnable is null
91 public FutureTask(Runnable runnable, V result) {
92 sync = new Sync(Executors.callable(runnable, result));
95 public boolean isCancelled() {
96 return sync.innerIsCancelled();
99 public boolean isDone() {
100 return sync.innerIsDone();
103 public boolean cancel(boolean mayInterruptIfRunning) {
104 return sync.innerCancel(mayInterruptIfRunning);
108 * @throws CancellationException {@inheritDoc}
110 public V get() throws InterruptedException, ExecutionException {
111 return sync.innerGet();
115 * @throws CancellationException {@inheritDoc}
117 public V get(long timeout, TimeUnit unit)
118 throws InterruptedException, ExecutionException, TimeoutException {
119 return sync.innerGet(unit.toNanos(timeout));
123 * Protected method invoked when this task transitions to state
124 * <tt>isDone</tt> (whether normally or via cancellation). The
125 * default implementation does nothing. Subclasses may override
126 * this method to invoke completion callbacks or perform
127 * bookkeeping. Note that you can query status inside the
128 * implementation of this method to determine whether this task
129 * has been cancelled.
131 protected void done() { }
134 * Sets the result of this Future to the given value unless
135 * this future has already been set or has been cancelled.
136 * This method is invoked internally by the <tt>run</tt> method
137 * upon successful completion of the computation.
140 protected void set(V v) {
145 * Causes this future to report an <tt>ExecutionException</tt>
146 * with the given throwable as its cause, unless this Future has
147 * already been set or has been cancelled.
148 * This method is invoked internally by the <tt>run</tt> method
149 * upon failure of the computation.
150 * @param t the cause of failure
152 protected void setException(Throwable t) {
153 sync.innerSetException(t);
156 // The following (duplicated) doc comment can be removed once
158 // 6270645: Javadoc comments should be inherited from most derived
159 // superinterface or superclass
162 * Sets this Future to the result of its computation
163 * unless it has been cancelled.
170 * Executes the computation without setting its result, and then
171 * resets this Future to initial state, failing to do so if the
172 * computation encounters an exception or is cancelled. This is
173 * designed for use with tasks that intrinsically execute more
175 * @return true if successfully run and reset
177 protected boolean runAndReset() {
178 return sync.innerRunAndReset();
182 * Synchronization control for FutureTask. Note that this must be
183 * a non-static inner class in order to invoke the protected
184 * <tt>done</tt> method. For clarity, all inner class support
185 * methods are same as outer, prefixed with "inner".
187 * Uses AQS sync state to represent run status
189 private final class Sync extends AbstractQueuedSynchronizer {
190 private static final long serialVersionUID = -7828117401763700385L;
192 /** State value representing that task is ready to run */
193 private static final int READY = 0;
194 /** State value representing that task is running */
195 private static final int RUNNING = 1;
196 /** State value representing that task ran */
197 private static final int RAN = 2;
198 /** State value representing that task was cancelled */
199 private static final int CANCELLED = 4;
201 /** The underlying callable */
202 private final Callable<V> callable;
203 /** The result to return from get() */
205 /** The exception to throw from get() */
206 private Throwable exception;
209 * The thread running task. When nulled after set/cancel, this
210 * indicates that the results are accessible. Must be
211 * volatile, to ensure visibility upon completion.
213 private volatile Thread runner;
215 Sync(Callable<V> callable) {
216 this.callable = callable;
219 private boolean ranOrCancelled(int state) {
220 return (state & (RAN | CANCELLED)) != 0;
224 * Implements AQS base acquire to succeed if ran or cancelled
226 protected int tryAcquireShared(int ignore) {
227 return innerIsDone() ? 1 : -1;
231 * Implements AQS base release to always signal after setting
232 * final done status by nulling runner thread.
234 protected boolean tryReleaseShared(int ignore) {
239 boolean innerIsCancelled() {
240 return getState() == CANCELLED;
243 boolean innerIsDone() {
244 return ranOrCancelled(getState()) && runner == null;
247 V innerGet() throws InterruptedException, ExecutionException {
248 acquireSharedInterruptibly(0);
249 if (getState() == CANCELLED)
250 throw new CancellationException();
251 if (exception != null)
252 throw new ExecutionException(exception);
256 V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
257 if (!tryAcquireSharedNanos(0, nanosTimeout))
258 throw new TimeoutException();
259 if (getState() == CANCELLED)
260 throw new CancellationException();
261 if (exception != null)
262 throw new ExecutionException(exception);
271 if (s == CANCELLED) {
272 // aggressively release to set runner to null,
273 // in case we are racing with a cancel request
274 // that will try to interrupt runner
278 if (compareAndSetState(s, RAN)) {
287 void innerSetException(Throwable t) {
292 if (s == CANCELLED) {
293 // aggressively release to set runner to null,
294 // in case we are racing with a cancel request
295 // that will try to interrupt runner
299 if (compareAndSetState(s, RAN)) {
308 boolean innerCancel(boolean mayInterruptIfRunning) {
311 if (ranOrCancelled(s))
313 if (compareAndSetState(s, CANCELLED))
316 if (mayInterruptIfRunning) {
327 if (!compareAndSetState(READY, RUNNING))
330 runner = Thread.currentThread();
331 if (getState() == RUNNING) { // recheck after setting thread
334 result = callable.call();
335 } catch (Throwable ex) {
341 releaseShared(0); // cancel
345 boolean innerRunAndReset() {
346 if (!compareAndSetState(READY, RUNNING))
349 runner = Thread.currentThread();
350 if (getState() == RUNNING)
351 callable.call(); // don't set result
353 return compareAndSetState(RUNNING, READY);
354 } catch (Throwable ex) {