1. /*
  2. * @(#)FutureTask.java 1.7 04/04/15
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util.concurrent;
  8. import java.util.concurrent.locks.*;
  9. /**
  10. * A cancellable asynchronous computation. This class provides a base
  11. * implementation of {@link Future}, with methods to start and cancel
  12. * a computation, query to see if the computation is complete, and
  13. * retrieve the result of the computation. The result can only be
  14. * retrieved when the computation has completed; the <tt>get</tt>
  15. * method will block if the computation has not yet completed. Once
  16. * the computation has completed, the computation cannot be restarted
  17. * or cancelled.
  18. *
  19. * <p>A <tt>FutureTask</tt> can be used to wrap a {@link Callable} or
  20. * {@link java.lang.Runnable} object. Because <tt>FutureTask</tt>
  21. * implements <tt>Runnable</tt>, a <tt>FutureTask</tt> can be
  22. * submitted to an {@link Executor} for execution.
  23. *
  24. * <p>In addition to serving as a standalone class, this class provides
  25. * <tt>protected</tt> functionality that may be useful when creating
  26. * customized task classes.
  27. *
  28. * @since 1.5
  29. * @author Doug Lea
  30. * @param <V> The result type returned by this FutureTask's <tt>get</tt> method
  31. */
  32. public class FutureTask<V> implements Future<V>, Runnable {
  33. /** Synchronization control for FutureTask */
  34. private final Sync sync;
  35. /**
  36. * Creates a <tt>FutureTask</tt> that will upon running, execute the
  37. * given <tt>Callable</tt>.
  38. *
  39. * @param callable the callable task
  40. * @throws NullPointerException if callable is null
  41. */
  42. public FutureTask(Callable<V> callable) {
  43. if (callable == null)
  44. throw new NullPointerException();
  45. sync = new Sync(callable);
  46. }
  47. /**
  48. * Creates a <tt>FutureTask</tt> that will upon running, execute the
  49. * given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the
  50. * given result on successful completion.
  51. *
  52. * @param runnable the runnable task
  53. * @param result the result to return on successful completion. If
  54. * you don't need a particular result, consider using
  55. * constructions of the form:
  56. * <tt>Future<?> f = new FutureTask<Object>(runnable, null)</tt>
  57. * @throws NullPointerException if runnable is null
  58. */
  59. public FutureTask(Runnable runnable, V result) {
  60. sync = new Sync(Executors.callable(runnable, result));
  61. }
  62. public boolean isCancelled() {
  63. return sync.innerIsCancelled();
  64. }
  65. public boolean isDone() {
  66. return sync.innerIsDone();
  67. }
  68. public boolean cancel(boolean mayInterruptIfRunning) {
  69. return sync.innerCancel(mayInterruptIfRunning);
  70. }
  71. public V get() throws InterruptedException, ExecutionException {
  72. return sync.innerGet();
  73. }
  74. public V get(long timeout, TimeUnit unit)
  75. throws InterruptedException, ExecutionException, TimeoutException {
  76. return sync.innerGet(unit.toNanos(timeout));
  77. }
  78. /**
  79. * Protected method invoked when this task transitions to state
  80. * <tt>isDone</tt> (whether normally or via cancellation). The
  81. * default implementation does nothing. Subclasses may override
  82. * this method to invoke completion callbacks or perform
  83. * bookkeeping. Note that you can query status inside the
  84. * implementation of this method to determine whether this task
  85. * has been cancelled.
  86. */
  87. protected void done() { }
  88. /**
  89. * Sets the result of this Future to the given value unless
  90. * this future has already been set or has been cancelled.
  91. * @param v the value
  92. */
  93. protected void set(V v) {
  94. sync.innerSet(v);
  95. }
  96. /**
  97. * Causes this future to report an <tt>ExecutionException</tt>
  98. * with the given throwable as its cause, unless this Future has
  99. * already been set or has been cancelled.
  100. * @param t the cause of failure.
  101. */
  102. protected void setException(Throwable t) {
  103. sync.innerSetException(t);
  104. }
  105. /**
  106. * Sets this Future to the result of computation unless
  107. * it has been cancelled.
  108. */
  109. public void run() {
  110. sync.innerRun();
  111. }
  112. /**
  113. * Executes the computation without setting its result, and then
  114. * resets this Future to initial state, failing to do so if the
  115. * computation encounters an exception or is cancelled. This is
  116. * designed for use with tasks that intrinsically execute more
  117. * than once.
  118. * @return true if successfully run and reset
  119. */
  120. protected boolean runAndReset() {
  121. return sync.innerRunAndReset();
  122. }
  123. /**
  124. * Synchronization control for FutureTask. Note that this must be
  125. * a non-static inner class in order to invoke the protected
  126. * <tt>done</tt> method. For clarity, all inner class support
  127. * methods are same as outer, prefixed with "inner".
  128. *
  129. * Uses AQS sync state to represent run status
  130. */
  131. private final class Sync extends AbstractQueuedSynchronizer {
  132. /** State value representing that task is running */
  133. private static final int RUNNING = 1;
  134. /** State value representing that task ran */
  135. private static final int RAN = 2;
  136. /** State value representing that task was cancelled */
  137. private static final int CANCELLED = 4;
  138. /** The underlying callable */
  139. private final Callable<V> callable;
  140. /** The result to return from get() */
  141. private V result;
  142. /** The exception to throw from get() */
  143. private Throwable exception;
  144. /**
  145. * The thread running task. When nulled after set/cancel, this
  146. * indicates that the results are accessible. Must be
  147. * volatile, to ensure visibility upon completion.
  148. */
  149. private volatile Thread runner;
  150. Sync(Callable<V> callable) {
  151. this.callable = callable;
  152. }
  153. private boolean ranOrCancelled(int state) {
  154. return (state & (RAN | CANCELLED)) != 0;
  155. }
  156. /**
  157. * Implements AQS base acquire to succeed if ran or cancelled
  158. */
  159. protected int tryAcquireShared(int ignore) {
  160. return innerIsDone()? 1 : -1;
  161. }
  162. /**
  163. * Implements AQS base release to always signal after setting
  164. * final done status by nulling runner thread.
  165. */
  166. protected boolean tryReleaseShared(int ignore) {
  167. runner = null;
  168. return true;
  169. }
  170. boolean innerIsCancelled() {
  171. return getState() == CANCELLED;
  172. }
  173. boolean innerIsDone() {
  174. return ranOrCancelled(getState()) && runner == null;
  175. }
  176. V innerGet() throws InterruptedException, ExecutionException {
  177. acquireSharedInterruptibly(0);
  178. if (getState() == CANCELLED)
  179. throw new CancellationException();
  180. if (exception != null)
  181. throw new ExecutionException(exception);
  182. return result;
  183. }
  184. V innerGet(long nanosTimeout) throws InterruptedException, ExecutionException, TimeoutException {
  185. if (!tryAcquireSharedNanos(0, nanosTimeout))
  186. throw new TimeoutException();
  187. if (getState() == CANCELLED)
  188. throw new CancellationException();
  189. if (exception != null)
  190. throw new ExecutionException(exception);
  191. return result;
  192. }
  193. void innerSet(V v) {
  194. for (;;) {
  195. int s = getState();
  196. if (ranOrCancelled(s))
  197. return;
  198. if (compareAndSetState(s, RAN))
  199. break;
  200. }
  201. result = v;
  202. releaseShared(0);
  203. done();
  204. }
  205. void innerSetException(Throwable t) {
  206. for (;;) {
  207. int s = getState();
  208. if (ranOrCancelled(s))
  209. return;
  210. if (compareAndSetState(s, RAN))
  211. break;
  212. }
  213. exception = t;
  214. result = null;
  215. releaseShared(0);
  216. done();
  217. }
  218. boolean innerCancel(boolean mayInterruptIfRunning) {
  219. for (;;) {
  220. int s = getState();
  221. if (ranOrCancelled(s))
  222. return false;
  223. if (compareAndSetState(s, CANCELLED))
  224. break;
  225. }
  226. if (mayInterruptIfRunning) {
  227. Thread r = runner;
  228. if (r != null)
  229. r.interrupt();
  230. }
  231. releaseShared(0);
  232. done();
  233. return true;
  234. }
  235. void innerRun() {
  236. if (!compareAndSetState(0, RUNNING))
  237. return;
  238. try {
  239. runner = Thread.currentThread();
  240. innerSet(callable.call());
  241. } catch(Throwable ex) {
  242. innerSetException(ex);
  243. }
  244. }
  245. boolean innerRunAndReset() {
  246. if (!compareAndSetState(0, RUNNING))
  247. return false;
  248. try {
  249. runner = Thread.currentThread();
  250. callable.call(); // don't set result
  251. runner = null;
  252. return compareAndSetState(RUNNING, 0);
  253. } catch(Throwable ex) {
  254. innerSetException(ex);
  255. return false;
  256. }
  257. }
  258. }
  259. }