12 |
|
* implementation of {@link Future}, with methods to start and cancel |
13 |
|
* a computation, query to see if the computation is complete, and |
14 |
|
* 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 |
15 |
> |
* retrieved when the computation has completed; the {@code get} |
16 |
> |
* methods will block if the computation has not yet completed. Once |
17 |
|
* the computation has completed, the computation cannot be restarted |
18 |
< |
* or cancelled. |
18 |
> |
* or cancelled (unless the computation is invoked using |
19 |
> |
* {@link #runAndReset}). |
20 |
|
* |
21 |
< |
* <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. |
21 |
> |
* <p>A {@code FutureTask} can be used to wrap a {@link Callable} or |
22 |
> |
* {@link Runnable} object. Because {@code FutureTask} implements |
23 |
> |
* {@code Runnable}, a {@code FutureTask} can be submitted to an |
24 |
> |
* {@link Executor} for execution. |
25 |
|
* |
26 |
|
* <p>In addition to serving as a standalone class, this class provides |
27 |
< |
* <tt>protected</tt> functionality that may be useful when creating |
27 |
> |
* {@code protected} functionality that may be useful when creating |
28 |
|
* customized task classes. |
29 |
|
* |
30 |
|
* @since 1.5 |
31 |
|
* @author Doug Lea |
32 |
< |
* @param <V> The result type returned by this FutureTask's <tt>get</tt> method |
32 |
> |
* @param <V> The result type returned by this FutureTask's {@code get} methods |
33 |
|
*/ |
34 |
|
public class FutureTask<V> implements RunnableFuture<V> { |
35 |
|
/* |
49 |
|
* transitions to NORMAL, EXCEPTIONAL, or CANCELLED (only) in |
50 |
|
* method setCompletion. During setCompletion, state may take on |
51 |
|
* transient values of COMPLETING (while outcome is being set) or |
52 |
< |
* INTERRUPTING (while interrupting the runner). State values |
52 |
> |
* INTERRUPTING (while interrupting the runner). State values |
53 |
|
* are ordered and set to powers of two to simplify checks. |
54 |
|
*/ |
55 |
|
private volatile int state; |
59 |
|
private static final int EXCEPTIONAL = 0x08; |
60 |
|
private static final int CANCELLED = 0x10; |
61 |
|
|
62 |
+ |
/** The underlying callable */ |
63 |
+ |
private final Callable<V> callable; |
64 |
|
/** The result to return or exception to throw from get() */ |
65 |
|
private Object outcome; // non-volatile, protected by state reads/writes |
66 |
|
/** The thread running the callable; CASed during run() */ |
67 |
|
private volatile Thread runner; |
65 |
– |
/** The underlying callable */ |
66 |
– |
private final Callable<V> callable; |
68 |
|
/** Treiber stack of waiting threads */ |
69 |
|
private volatile WaitNode waiters; |
70 |
|
|
71 |
|
/** |
72 |
|
* Sets completion status, unless already completed. If |
73 |
|
* necessary, we first set state to COMPLETING or INTERRUPTING to |
74 |
< |
* establish precedence. This intentionally stalls (just via |
74 |
> |
* establish precedence. This intentionally stalls (just via |
75 |
|
* yields) in (uncommon) cases of concurrent calls during |
76 |
|
* cancellation until state is set, to avoid surprising users |
77 |
|
* during cancellation races. |
78 |
|
* |
79 |
|
* @param x the outcome |
80 |
|
* @param mode the completion state value |
81 |
< |
* @return true if this call caused transtion from 0 to completed |
81 |
> |
* @return true if this call caused transition from 0 to completed |
82 |
|
*/ |
83 |
|
private boolean setCompletion(Object x, int mode) { |
84 |
|
Thread r = runner; |
87 |
|
int next = ((mode == INTERRUPTING) ? // set up transient states |
88 |
|
(r != null) ? INTERRUPTING : CANCELLED : |
89 |
|
(x != null) ? COMPLETING : mode); |
90 |
< |
for (int s;;) { |
91 |
< |
if ((s = state) == 0) { |
90 |
> |
for (;;) { |
91 |
> |
int s = state; |
92 |
> |
if (s == 0) { |
93 |
|
if (UNSAFE.compareAndSwapInt(this, stateOffset, 0, next)) { |
94 |
|
if (next == INTERRUPTING) { |
95 |
|
Thread t = runner; // recheck |
108 |
|
} |
109 |
|
} |
110 |
|
else if (s == INTERRUPTING) |
111 |
< |
Thread.yield(); // wait out cancellation |
111 |
> |
Thread.yield(); // wait out pending cancellation interrupt |
112 |
|
else |
113 |
|
return false; |
114 |
|
} |
115 |
|
} |
116 |
|
|
117 |
|
/** |
118 |
< |
* Returns result or throws exception for completed task |
118 |
> |
* Returns result or throws exception for completed task. |
119 |
> |
* |
120 |
|
* @param s completed state value |
121 |
|
*/ |
122 |
|
private V report(int s) throws ExecutionException { |
129 |
|
} |
130 |
|
|
131 |
|
/** |
132 |
< |
* Creates a <tt>FutureTask</tt> that will, upon running, execute the |
133 |
< |
* given <tt>Callable</tt>. |
132 |
> |
* Creates a {@code FutureTask} that will, upon running, execute the |
133 |
> |
* given {@code Callable}. |
134 |
|
* |
135 |
|
* @param callable the callable task |
136 |
|
* @throws NullPointerException if callable is null |
142 |
|
} |
143 |
|
|
144 |
|
/** |
145 |
< |
* Creates a <tt>FutureTask</tt> that will, upon running, execute the |
146 |
< |
* given <tt>Runnable</tt>, and arrange that <tt>get</tt> will return the |
145 |
> |
* Creates a {@code FutureTask} that will, upon running, execute the |
146 |
> |
* given {@code Runnable}, and arrange that {@code get} will return the |
147 |
|
* given result on successful completion. |
148 |
|
* |
149 |
|
* @param runnable the runnable task |
175 |
|
* @throws CancellationException {@inheritDoc} |
176 |
|
*/ |
177 |
|
public V get() throws InterruptedException, ExecutionException { |
178 |
< |
int s; |
179 |
< |
return report((s = state) > COMPLETING ? s : awaitDone(false, 0L)); |
178 |
> |
int s = state; |
179 |
> |
if (s <= COMPLETING) |
180 |
> |
s = awaitDone(false, 0L); |
181 |
> |
return report(s); |
182 |
|
} |
183 |
|
|
184 |
|
/** |
186 |
|
*/ |
187 |
|
public V get(long timeout, TimeUnit unit) |
188 |
|
throws InterruptedException, ExecutionException, TimeoutException { |
189 |
< |
int s; |
190 |
< |
long nanos = unit.toNanos(timeout); |
191 |
< |
if ((s = state) <= COMPLETING && |
187 |
< |
(s = awaitDone(true, nanos)) <= COMPLETING) |
189 |
> |
int s = state; |
190 |
> |
if (s <= COMPLETING && |
191 |
> |
(s = awaitDone(true, unit.toNanos(timeout))) <= COMPLETING) |
192 |
|
throw new TimeoutException(); |
193 |
|
return report(s); |
194 |
|
} |
195 |
|
|
196 |
|
/** |
197 |
|
* Protected method invoked when this task transitions to state |
198 |
< |
* <tt>isDone</tt> (whether normally or via cancellation). The |
198 |
> |
* {@code isDone} (whether normally or via cancellation). The |
199 |
|
* default implementation does nothing. Subclasses may override |
200 |
|
* this method to invoke completion callbacks or perform |
201 |
|
* bookkeeping. Note that you can query status inside the |
205 |
|
protected void done() { } |
206 |
|
|
207 |
|
/** |
208 |
< |
* Sets the result of this Future to the given value unless |
208 |
> |
* Sets the result of this future to the given value unless |
209 |
|
* this future has already been set or has been cancelled. |
210 |
< |
* This method is invoked internally by the <tt>run</tt> method |
210 |
> |
* |
211 |
> |
* <p>This method is invoked internally by the {@link #run} method |
212 |
|
* upon successful completion of the computation. |
213 |
+ |
* |
214 |
|
* @param v the value |
215 |
|
*/ |
216 |
|
protected void set(V v) { |
218 |
|
} |
219 |
|
|
220 |
|
/** |
221 |
< |
* Causes this future to report an <tt>ExecutionException</tt> |
222 |
< |
* with the given throwable as its cause, unless this Future has |
221 |
> |
* Causes this future to report an {@link ExecutionException} |
222 |
> |
* with the given throwable as its cause, unless this future has |
223 |
|
* already been set or has been cancelled. |
224 |
< |
* This method is invoked internally by the <tt>run</tt> method |
224 |
> |
* |
225 |
> |
* <p>This method is invoked internally by the {@link #run} method |
226 |
|
* upon failure of the computation. |
227 |
+ |
* |
228 |
|
* @param t the cause of failure |
229 |
|
*/ |
230 |
|
protected void setException(Throwable t) { |
248 |
|
|
249 |
|
/** |
250 |
|
* Executes the computation without setting its result, and then |
251 |
< |
* resets this Future to initial state, failing to do so if the |
251 |
> |
* resets this future to initial state, failing to do so if the |
252 |
|
* computation encounters an exception or is cancelled. This is |
253 |
|
* designed for use with tasks that intrinsically execute more |
254 |
|
* than once. |
255 |
+ |
* |
256 |
|
* @return true if successfully run and reset |
257 |
|
*/ |
258 |
|
protected boolean runAndReset() { |
273 |
|
return true; |
274 |
|
if (s != INTERRUPTING) |
275 |
|
return false; |
276 |
< |
Thread.yield(); // wait out racing cancellation |
276 |
> |
Thread.yield(); // wait out pending cancellation interrupt |
277 |
|
} |
278 |
|
} |
279 |
|
|
280 |
|
/** |
281 |
|
* Simple linked list nodes to record waiting threads in a Treiber |
282 |
< |
* stack. See other classes such as Phaser and SynchronousQueue |
282 |
> |
* stack. See other classes such as Phaser and SynchronousQueue |
283 |
|
* for more detailed explanation. |
284 |
|
*/ |
285 |
|
static final class WaitNode { |
288 |
|
} |
289 |
|
|
290 |
|
/** |
291 |
< |
* Removes and signals all waiting threads |
291 |
> |
* Removes and signals all waiting threads. |
292 |
|
*/ |
293 |
|
private void releaseAll() { |
294 |
|
WaitNode q; |
311 |
|
} |
312 |
|
|
313 |
|
/** |
314 |
< |
* Awaits completion or aborts on interrupt of timeout |
314 |
> |
* Awaits completion or aborts on interrupt or timeout. |
315 |
> |
* |
316 |
|
* @param timed true if use timed waits |
317 |
< |
* @param nanos time to wait if timed |
317 |
> |
* @param nanos time to wait, if timed |
318 |
|
* @return state upon completion |
319 |
|
*/ |
320 |
|
private int awaitDone(boolean timed, long nanos) |
322 |
|
long last = timed ? System.nanoTime() : 0L; |
323 |
|
WaitNode q = null; |
324 |
|
boolean queued = false; |
325 |
< |
for (int s;;) { |
325 |
> |
for (;;) { |
326 |
|
if (Thread.interrupted()) { |
327 |
|
removeWaiter(q); |
328 |
|
throw new InterruptedException(); |
329 |
|
} |
330 |
< |
else if ((s = state) > COMPLETING) { |
330 |
> |
|
331 |
> |
int s = state; |
332 |
> |
if (s > COMPLETING) { |
333 |
|
if (q != null) |
334 |
|
q.thread = null; |
335 |
|
return s; |
356 |
|
} |
357 |
|
|
358 |
|
/** |
359 |
< |
* Try to unlink a timed-out or interrupted wait node to avoid |
360 |
< |
* accumulating garbage. Internal nodes are simply unspliced |
359 |
> |
* Tries to unlink a timed-out or interrupted wait node to avoid |
360 |
> |
* accumulating garbage. Internal nodes are simply unspliced |
361 |
|
* without CAS since it is harmless if they are traversed anyway |
362 |
|
* by releasers or concurrent calls to removeWaiter. |
363 |
|
*/ |