153 |
|
|
154 |
|
/** |
155 |
|
* Implementation of Future methods under the control of a current |
156 |
< |
* CancellableTask. This is split into an inner class to permit |
157 |
< |
* Future support to be mixed-in with other flavors of tasks. |
156 |
> |
* <tt>CancellableTask</tt>, which it relies on for methods |
157 |
> |
* <tt>isDone</tt>, <tt>isCancelled</tt> and <tt>cancel</tt>. This |
158 |
> |
* class is split into an inner class to permit Future support to |
159 |
> |
* be mixed-in with other flavors of tasks. Normally, such a |
160 |
> |
* class will delegate <tt>Future</tt> <tt>get</tt> methods to the |
161 |
> |
* <tt>InnerCancellableFuture</tt>, and internally arrange that |
162 |
> |
* <tt>set</tt> methods be invoked when computations are ready. |
163 |
> |
* |
164 |
> |
* <p><b>Sample Usage</b>. Here are fragments of an example subclass. |
165 |
> |
* <pre> |
166 |
> |
* class MyFutureTask<V> extends CancellableTask implements Future< |
167 |
> |
V> { |
168 |
> |
* |
169 |
> |
* MyFutureTask(Callable<V> callable) { |
170 |
> |
* setRunnable(new InnerCancellableFuture<V>(callable)); |
171 |
> |
* } |
172 |
> |
* |
173 |
> |
* public V get() throws InterruptedException, ExecutionException { |
174 |
> |
* return ((InnerCancellableFuture<V>)getRunnable()).get(); |
175 |
> |
* } |
176 |
> |
* // (And similarly for timeout version.) |
177 |
> |
* |
178 |
> |
* void action() { // whatever action causes execution |
179 |
> |
* try { |
180 |
> |
* ((InnerCancellableFuture<V>)getRunnable()).set(compute()); |
181 |
> |
* } catch (Exception ex) { |
182 |
> |
* ((InnerCancellableFuture<V>)getRunnable()).setException(ex); |
183 |
> |
* } |
184 |
> |
* } |
185 |
> |
* } |
186 |
> |
*</pre> |
187 |
|
*/ |
188 |
|
protected class InnerCancellableFuture<V> implements Future<V>, Runnable { |
189 |
|
private final Callable<V> callable; |
214 |
|
return CancellableTask.this.isDone(); |
215 |
|
} |
216 |
|
|
217 |
+ |
|
218 |
+ |
/** |
219 |
+ |
* Sets this Future to the results of <tt>callable.call</tt> |
220 |
+ |
*/ |
221 |
|
public void run() { |
222 |
|
try { |
223 |
|
set(callable.call()); |
226 |
|
} |
227 |
|
} |
228 |
|
|
229 |
+ |
/** |
230 |
+ |
* Waits if necessary for the call to <tt>callable.call</tt> to |
231 |
+ |
* complete, and then retrieves its result. |
232 |
+ |
* |
233 |
+ |
* @return computed result |
234 |
+ |
* @throws CancellationException here??? |
235 |
+ |
* @throws ExecutionException if underlying computation threw an |
236 |
+ |
* exception |
237 |
+ |
* @throws InterruptedException if current thread was interrupted |
238 |
+ |
* while waiting |
239 |
+ |
*/ |
240 |
|
public V get() throws InterruptedException, ExecutionException { |
241 |
|
lock.lock(); |
242 |
|
try { |
253 |
|
} |
254 |
|
} |
255 |
|
|
256 |
+ |
/** |
257 |
+ |
* Waits if necessary for at most the given time for the call to |
258 |
+ |
* <tt>callable.call</tt> to complete, and then retrieves its |
259 |
+ |
* result. |
260 |
+ |
* |
261 |
+ |
* @param timeout the maximum time to wait |
262 |
+ |
* @param granularity the time unit of the timeout argument |
263 |
+ |
* @return computed result |
264 |
+ |
* @throws ExecutionException if underlying computation threw an |
265 |
+ |
* exception |
266 |
+ |
* @throws InterruptedException if current thread was interrupted |
267 |
+ |
* while waiting |
268 |
+ |
* @throws TimeoutException if the wait timed out |
269 |
+ |
*/ |
270 |
|
public V get(long timeout, TimeUnit unit) |
271 |
|
throws InterruptedException, ExecutionException, TimeoutException { |
272 |
|
lock.lock(); |
290 |
|
} |
291 |
|
} |
292 |
|
|
293 |
+ |
/** |
294 |
+ |
* Sets the result of this Future to the given value. |
295 |
+ |
* @param v the value |
296 |
+ |
*/ |
297 |
|
protected void set(V v) { |
298 |
|
lock.lock(); |
299 |
|
try { |
305 |
|
} |
306 |
|
} |
307 |
|
|
308 |
+ |
/** |
309 |
+ |
* Causes this futue to report an <tt>ExecutionException</tt> |
310 |
+ |
* with the given throwable as its cause. |
311 |
+ |
* @param t the cause of failure. |
312 |
+ |
*/ |
313 |
|
protected void setException(Throwable t) { |
314 |
|
lock.lock(); |
315 |
|
try { |