Parent Directory
|
Revision Log
Revision 1.28 - (view) (download)
1 : | dl | 1.1 | /* |
2 : | dl | 1.10 | * Written by Doug Lea with assistance from members of JCP JSR-166 |
3 : | * Expert Group and released to the public domain, as explained at | ||
4 : | jsr166 | 1.24 | * http://creativecommons.org/publicdomain/zero/1.0/ |
5 : | jsr166 | 1.12 | * Other contributors include Andrew Wright, Jeffrey Hayes, |
6 : | * Pat Fisher, Mike Judd. | ||
7 : | dl | 1.1 | */ |
8 : | |||
9 : | import junit.framework.*; | ||
10 : | jsr166 | 1.26 | import java.util.concurrent.Callable; |
11 : | import java.util.concurrent.CancellationException; | ||
12 : | import java.util.concurrent.CountDownLatch; | ||
13 : | import java.util.concurrent.ExecutionException; | ||
14 : | import java.util.concurrent.Future; | ||
15 : | import java.util.concurrent.FutureTask; | ||
16 : | import java.util.concurrent.TimeoutException; | ||
17 : | jsr166 | 1.15 | import static java.util.concurrent.TimeUnit.MILLISECONDS; |
18 : | jsr166 | 1.22 | import static java.util.concurrent.TimeUnit.SECONDS; |
19 : | dl | 1.4 | import java.util.*; |
20 : | dl | 1.1 | |
21 : | dl | 1.4 | public class FutureTaskTest extends JSR166TestCase { |
22 : | dl | 1.1 | |
23 : | public static void main(String[] args) { | ||
24 : | jsr166 | 1.19 | junit.textui.TestRunner.run(suite()); |
25 : | dl | 1.1 | } |
26 : | public static Test suite() { | ||
27 : | jsr166 | 1.16 | return new TestSuite(FutureTaskTest.class); |
28 : | dl | 1.1 | } |
29 : | |||
30 : | jsr166 | 1.22 | void checkNotDone(Future<?> f) { |
31 : | assertFalse(f.isDone()); | ||
32 : | assertFalse(f.isCancelled()); | ||
33 : | } | ||
34 : | |||
35 : | <T> void checkCompletedNormally(Future<T> f, T expected) { | ||
36 : | assertTrue(f.isDone()); | ||
37 : | assertFalse(f.isCancelled()); | ||
38 : | |||
39 : | try { | ||
40 : | assertSame(expected, f.get()); | ||
41 : | } catch (Throwable fail) { threadUnexpectedException(fail); } | ||
42 : | try { | ||
43 : | assertSame(expected, f.get(5L, SECONDS)); | ||
44 : | } catch (Throwable fail) { threadUnexpectedException(fail); } | ||
45 : | |||
46 : | assertFalse(f.cancel(false)); | ||
47 : | assertFalse(f.cancel(true)); | ||
48 : | } | ||
49 : | |||
50 : | void checkCancelled(Future<?> f) { | ||
51 : | assertTrue(f.isDone()); | ||
52 : | assertTrue(f.isCancelled()); | ||
53 : | |||
54 : | try { | ||
55 : | f.get(); | ||
56 : | shouldThrow(); | ||
57 : | } catch (CancellationException success) { | ||
58 : | } catch (Throwable fail) { threadUnexpectedException(fail); } | ||
59 : | |||
60 : | try { | ||
61 : | f.get(5L, SECONDS); | ||
62 : | shouldThrow(); | ||
63 : | } catch (CancellationException success) { | ||
64 : | } catch (Throwable fail) { threadUnexpectedException(fail); } | ||
65 : | |||
66 : | assertFalse(f.cancel(false)); | ||
67 : | assertFalse(f.cancel(true)); | ||
68 : | } | ||
69 : | |||
70 : | void checkCompletedAbnormally(Future<?> f, Throwable t) { | ||
71 : | assertTrue(f.isDone()); | ||
72 : | assertFalse(f.isCancelled()); | ||
73 : | |||
74 : | try { | ||
75 : | f.get(); | ||
76 : | shouldThrow(); | ||
77 : | } catch (ExecutionException success) { | ||
78 : | assertSame(t, success.getCause()); | ||
79 : | } catch (Throwable fail) { threadUnexpectedException(fail); } | ||
80 : | |||
81 : | try { | ||
82 : | f.get(5L, SECONDS); | ||
83 : | shouldThrow(); | ||
84 : | } catch (ExecutionException success) { | ||
85 : | assertSame(t, success.getCause()); | ||
86 : | } catch (Throwable fail) { threadUnexpectedException(fail); } | ||
87 : | |||
88 : | assertFalse(f.cancel(false)); | ||
89 : | assertFalse(f.cancel(true)); | ||
90 : | } | ||
91 : | |||
92 : | dl | 1.4 | /** |
93 : | * Subclass to expose protected methods | ||
94 : | */ | ||
95 : | dl | 1.7 | static class PublicFutureTask extends FutureTask { |
96 : | public PublicFutureTask(Callable r) { super(r); } | ||
97 : | dl | 1.9 | public boolean runAndReset() { return super.runAndReset(); } |
98 : | dl | 1.4 | public void set(Object x) { super.set(x); } |
99 : | public void setException(Throwable t) { super.setException(t); } | ||
100 : | } | ||
101 : | dl | 1.1 | |
102 : | dl | 1.5 | /** |
103 : | dl | 1.6 | * Creating a future with a null callable throws NPE |
104 : | dl | 1.5 | */ |
105 : | public void testConstructor() { | ||
106 : | dl | 1.3 | try { |
107 : | FutureTask task = new FutureTask(null); | ||
108 : | jsr166 | 1.17 | shouldThrow(); |
109 : | jsr166 | 1.15 | } catch (NullPointerException success) {} |
110 : | dl | 1.3 | } |
111 : | |||
112 : | dl | 1.5 | /** |
113 : | dl | 1.6 | * creating a future with null runnable fails |
114 : | dl | 1.5 | */ |
115 : | public void testConstructor2() { | ||
116 : | dl | 1.3 | try { |
117 : | FutureTask task = new FutureTask(null, Boolean.TRUE); | ||
118 : | jsr166 | 1.17 | shouldThrow(); |
119 : | jsr166 | 1.15 | } catch (NullPointerException success) {} |
120 : | dl | 1.3 | } |
121 : | |||
122 : | dl | 1.5 | /** |
123 : | dl | 1.6 | * isDone is true when a task completes |
124 : | dl | 1.5 | */ |
125 : | public void testIsDone() { | ||
126 : | jsr166 | 1.15 | FutureTask task = new FutureTask(new NoOpCallable()); |
127 : | jsr166 | 1.16 | task.run(); |
128 : | assertTrue(task.isDone()); | ||
129 : | jsr166 | 1.22 | checkCompletedNormally(task, Boolean.TRUE); |
130 : | dl | 1.4 | } |
131 : | |||
132 : | dl | 1.5 | /** |
133 : | dl | 1.9 | * runAndReset of a non-cancelled task succeeds |
134 : | dl | 1.5 | */ |
135 : | dl | 1.9 | public void testRunAndReset() { |
136 : | dl | 1.7 | PublicFutureTask task = new PublicFutureTask(new NoOpCallable()); |
137 : | jsr166 | 1.16 | assertTrue(task.runAndReset()); |
138 : | jsr166 | 1.22 | checkNotDone(task); |
139 : | dl | 1.4 | } |
140 : | |||
141 : | dl | 1.5 | /** |
142 : | dl | 1.9 | * runAndReset after cancellation fails |
143 : | dl | 1.5 | */ |
144 : | dl | 1.4 | public void testResetAfterCancel() { |
145 : | dl | 1.7 | PublicFutureTask task = new PublicFutureTask(new NoOpCallable()); |
146 : | dl | 1.4 | assertTrue(task.cancel(false)); |
147 : | jsr166 | 1.16 | assertFalse(task.runAndReset()); |
148 : | jsr166 | 1.22 | checkCancelled(task); |
149 : | dl | 1.4 | } |
150 : | |||
151 : | dl | 1.5 | /** |
152 : | dl | 1.11 | * setting value causes get to return it |
153 : | dl | 1.5 | */ |
154 : | jsr166 | 1.15 | public void testSet() throws Exception { |
155 : | dl | 1.7 | PublicFutureTask task = new PublicFutureTask(new NoOpCallable()); |
156 : | dl | 1.4 | task.set(one); |
157 : | jsr166 | 1.18 | assertSame(task.get(), one); |
158 : | jsr166 | 1.22 | checkCompletedNormally(task, one); |
159 : | dl | 1.4 | } |
160 : | |||
161 : | dl | 1.5 | /** |
162 : | dl | 1.6 | * setException causes get to throw ExecutionException |
163 : | dl | 1.5 | */ |
164 : | jsr166 | 1.15 | public void testSetException() throws Exception { |
165 : | dl | 1.4 | Exception nse = new NoSuchElementException(); |
166 : | dl | 1.7 | PublicFutureTask task = new PublicFutureTask(new NoOpCallable()); |
167 : | dl | 1.4 | task.setException(nse); |
168 : | try { | ||
169 : | Object x = task.get(); | ||
170 : | jsr166 | 1.17 | shouldThrow(); |
171 : | jsr166 | 1.15 | } catch (ExecutionException success) { |
172 : | assertSame(success.getCause(), nse); | ||
173 : | jsr166 | 1.22 | checkCompletedAbnormally(task, nse); |
174 : | dl | 1.4 | } |
175 : | } | ||
176 : | |||
177 : | dl | 1.5 | /** |
178 : | jsr166 | 1.21 | * Cancelling before running succeeds |
179 : | dl | 1.5 | */ |
180 : | dl | 1.1 | public void testCancelBeforeRun() { |
181 : | jsr166 | 1.15 | FutureTask task = new FutureTask(new NoOpCallable()); |
182 : | dl | 1.1 | assertTrue(task.cancel(false)); |
183 : | jsr166 | 1.16 | task.run(); |
184 : | jsr166 | 1.22 | checkCancelled(task); |
185 : | dl | 1.1 | } |
186 : | |||
187 : | dl | 1.5 | /** |
188 : | dl | 1.6 | * Cancel(true) before run succeeds |
189 : | dl | 1.5 | */ |
190 : | dl | 1.1 | public void testCancelBeforeRun2() { |
191 : | jsr166 | 1.15 | FutureTask task = new FutureTask(new NoOpCallable()); |
192 : | dl | 1.1 | assertTrue(task.cancel(true)); |
193 : | jsr166 | 1.16 | task.run(); |
194 : | jsr166 | 1.22 | checkCancelled(task); |
195 : | dl | 1.1 | } |
196 : | |||
197 : | dl | 1.5 | /** |
198 : | dl | 1.6 | * cancel of a completed task fails |
199 : | dl | 1.5 | */ |
200 : | dl | 1.1 | public void testCancelAfterRun() { |
201 : | jsr166 | 1.15 | FutureTask task = new FutureTask(new NoOpCallable()); |
202 : | jsr166 | 1.16 | task.run(); |
203 : | dl | 1.1 | assertFalse(task.cancel(false)); |
204 : | jsr166 | 1.22 | checkCompletedNormally(task, Boolean.TRUE); |
205 : | dl | 1.1 | } |
206 : | |||
207 : | dl | 1.5 | /** |
208 : | dl | 1.6 | * cancel(true) interrupts a running task |
209 : | dl | 1.5 | */ |
210 : | jsr166 | 1.15 | public void testCancelInterrupt() throws InterruptedException { |
211 : | jsr166 | 1.22 | final CountDownLatch threadStarted = new CountDownLatch(1); |
212 : | jsr166 | 1.16 | final FutureTask task = |
213 : | jsr166 | 1.22 | new FutureTask(new CheckedCallable<Object>() { |
214 : | public Object realCall() { | ||
215 : | threadStarted.countDown(); | ||
216 : | long t0 = System.nanoTime(); | ||
217 : | for (;;) { | ||
218 : | if (Thread.interrupted()) | ||
219 : | return Boolean.TRUE; | ||
220 : | if (millisElapsedSince(t0) > MEDIUM_DELAY_MS) | ||
221 : | fail("interrupt not delivered"); | ||
222 : | Thread.yield(); | ||
223 : | } | ||
224 : | jsr166 | 1.15 | }}); |
225 : | |||
226 : | jsr166 | 1.22 | Thread t = newStartedThread(task); |
227 : | threadStarted.await(); | ||
228 : | jsr166 | 1.15 | assertTrue(task.cancel(true)); |
229 : | jsr166 | 1.22 | checkCancelled(task); |
230 : | awaitTermination(t, MEDIUM_DELAY_MS); | ||
231 : | checkCancelled(task); | ||
232 : | dl | 1.1 | } |
233 : | |||
234 : | dl | 1.5 | /** |
235 : | dl | 1.6 | * cancel(false) does not interrupt a running task |
236 : | dl | 1.5 | */ |
237 : | jsr166 | 1.15 | public void testCancelNoInterrupt() throws InterruptedException { |
238 : | jsr166 | 1.22 | final CountDownLatch threadStarted = new CountDownLatch(1); |
239 : | final CountDownLatch cancelled = new CountDownLatch(1); | ||
240 : | final FutureTask<Boolean> task = | ||
241 : | new FutureTask<Boolean>(new CheckedCallable<Boolean>() { | ||
242 : | public Boolean realCall() throws InterruptedException { | ||
243 : | threadStarted.countDown(); | ||
244 : | cancelled.await(MEDIUM_DELAY_MS, MILLISECONDS); | ||
245 : | assertFalse(Thread.interrupted()); | ||
246 : | dl | 1.1 | return Boolean.TRUE; |
247 : | jsr166 | 1.15 | }}); |
248 : | |||
249 : | jsr166 | 1.22 | Thread t = newStartedThread(task); |
250 : | threadStarted.await(); | ||
251 : | jsr166 | 1.15 | assertTrue(task.cancel(false)); |
252 : | jsr166 | 1.22 | checkCancelled(task); |
253 : | cancelled.countDown(); | ||
254 : | awaitTermination(t, MEDIUM_DELAY_MS); | ||
255 : | checkCancelled(task); | ||
256 : | dl | 1.1 | } |
257 : | |||
258 : | dl | 1.5 | /** |
259 : | jsr166 | 1.23 | * run in one thread causes get in another thread to retrieve value |
260 : | dl | 1.5 | */ |
261 : | jsr166 | 1.23 | public void testGetRun() throws InterruptedException { |
262 : | final CountDownLatch threadStarted = new CountDownLatch(1); | ||
263 : | |||
264 : | jsr166 | 1.22 | final FutureTask task = |
265 : | jsr166 | 1.15 | new FutureTask(new CheckedCallable<Object>() { |
266 : | jsr166 | 1.16 | public Object realCall() throws InterruptedException { |
267 : | dl | 1.1 | return Boolean.TRUE; |
268 : | jsr166 | 1.15 | }}); |
269 : | jsr166 | 1.22 | |
270 : | Thread t = newStartedThread(new CheckedRunnable() { | ||
271 : | jsr166 | 1.15 | public void realRun() throws Exception { |
272 : | jsr166 | 1.23 | threadStarted.countDown(); |
273 : | jsr166 | 1.22 | assertSame(Boolean.TRUE, task.get()); |
274 : | jsr166 | 1.15 | }}); |
275 : | dl | 1.1 | |
276 : | jsr166 | 1.23 | threadStarted.await(); |
277 : | checkNotDone(task); | ||
278 : | assertTrue(t.isAlive()); | ||
279 : | jsr166 | 1.22 | task.run(); |
280 : | checkCompletedNormally(task, Boolean.TRUE); | ||
281 : | awaitTermination(t, MEDIUM_DELAY_MS); | ||
282 : | dl | 1.1 | } |
283 : | |||
284 : | dl | 1.5 | /** |
285 : | jsr166 | 1.23 | * set in one thread causes get in another thread to retrieve value |
286 : | */ | ||
287 : | public void testGetSet() throws InterruptedException { | ||
288 : | final CountDownLatch threadStarted = new CountDownLatch(1); | ||
289 : | |||
290 : | final PublicFutureTask task = | ||
291 : | new PublicFutureTask(new CheckedCallable<Object>() { | ||
292 : | public Object realCall() throws InterruptedException { | ||
293 : | return Boolean.TRUE; | ||
294 : | }}); | ||
295 : | |||
296 : | Thread t = newStartedThread(new CheckedRunnable() { | ||
297 : | public void realRun() throws Exception { | ||
298 : | threadStarted.countDown(); | ||
299 : | assertSame(Boolean.FALSE, task.get()); | ||
300 : | }}); | ||
301 : | |||
302 : | threadStarted.await(); | ||
303 : | checkNotDone(task); | ||
304 : | assertTrue(t.isAlive()); | ||
305 : | task.set(Boolean.FALSE); | ||
306 : | checkCompletedNormally(task, Boolean.FALSE); | ||
307 : | awaitTermination(t, MEDIUM_DELAY_MS); | ||
308 : | } | ||
309 : | |||
310 : | /** | ||
311 : | * run in one thread causes timed get in another thread to retrieve value | ||
312 : | dl | 1.5 | */ |
313 : | jsr166 | 1.23 | public void testTimedGetRun() throws InterruptedException { |
314 : | final CountDownLatch threadStarted = new CountDownLatch(1); | ||
315 : | |||
316 : | jsr166 | 1.22 | final FutureTask task = |
317 : | jsr166 | 1.15 | new FutureTask(new CheckedCallable<Object>() { |
318 : | jsr166 | 1.16 | public Object realCall() throws InterruptedException { |
319 : | dl | 1.1 | return Boolean.TRUE; |
320 : | jsr166 | 1.15 | }}); |
321 : | jsr166 | 1.22 | |
322 : | Thread t = newStartedThread(new CheckedRunnable() { | ||
323 : | jsr166 | 1.15 | public void realRun() throws Exception { |
324 : | jsr166 | 1.23 | threadStarted.countDown(); |
325 : | assertSame(Boolean.TRUE, | ||
326 : | task.get(MEDIUM_DELAY_MS, MILLISECONDS)); | ||
327 : | jsr166 | 1.15 | }}); |
328 : | jsr166 | 1.12 | |
329 : | jsr166 | 1.23 | threadStarted.await(); |
330 : | checkNotDone(task); | ||
331 : | assertTrue(t.isAlive()); | ||
332 : | jsr166 | 1.22 | task.run(); |
333 : | checkCompletedNormally(task, Boolean.TRUE); | ||
334 : | awaitTermination(t, MEDIUM_DELAY_MS); | ||
335 : | dl | 1.1 | } |
336 : | |||
337 : | dl | 1.5 | /** |
338 : | jsr166 | 1.23 | * set in one thread causes timed get in another thread to retrieve value |
339 : | */ | ||
340 : | public void testTimedGetSet() throws InterruptedException { | ||
341 : | final CountDownLatch threadStarted = new CountDownLatch(1); | ||
342 : | |||
343 : | final PublicFutureTask task = | ||
344 : | new PublicFutureTask(new CheckedCallable<Object>() { | ||
345 : | public Object realCall() throws InterruptedException { | ||
346 : | return Boolean.TRUE; | ||
347 : | }}); | ||
348 : | |||
349 : | Thread t = newStartedThread(new CheckedRunnable() { | ||
350 : | public void realRun() throws Exception { | ||
351 : | threadStarted.countDown(); | ||
352 : | assertSame(Boolean.FALSE, | ||
353 : | task.get(MEDIUM_DELAY_MS, MILLISECONDS)); | ||
354 : | }}); | ||
355 : | |||
356 : | threadStarted.await(); | ||
357 : | checkNotDone(task); | ||
358 : | assertTrue(t.isAlive()); | ||
359 : | task.set(Boolean.FALSE); | ||
360 : | checkCompletedNormally(task, Boolean.FALSE); | ||
361 : | awaitTermination(t, MEDIUM_DELAY_MS); | ||
362 : | } | ||
363 : | |||
364 : | /** | ||
365 : | jsr166 | 1.21 | * Cancelling a task causes timed get in another thread to throw |
366 : | * CancellationException | ||
367 : | dl | 1.5 | */ |
368 : | jsr166 | 1.15 | public void testTimedGet_Cancellation() throws InterruptedException { |
369 : | jsr166 | 1.22 | final CountDownLatch threadStarted = new CountDownLatch(2); |
370 : | final FutureTask task = | ||
371 : | jsr166 | 1.15 | new FutureTask(new CheckedInterruptedCallable<Object>() { |
372 : | jsr166 | 1.16 | public Object realCall() throws InterruptedException { |
373 : | jsr166 | 1.22 | threadStarted.countDown(); |
374 : | dl | 1.25 | delay(LONG_DELAY_MS); |
375 : | jsr166 | 1.16 | return Boolean.TRUE; |
376 : | jsr166 | 1.15 | }}); |
377 : | |||
378 : | Thread t1 = new ThreadShouldThrow(CancellationException.class) { | ||
379 : | public void realRun() throws Exception { | ||
380 : | jsr166 | 1.22 | threadStarted.countDown(); |
381 : | task.get(MEDIUM_DELAY_MS, MILLISECONDS); | ||
382 : | jsr166 | 1.15 | }}; |
383 : | jsr166 | 1.22 | Thread t2 = new Thread(task); |
384 : | jsr166 | 1.15 | t1.start(); |
385 : | t2.start(); | ||
386 : | jsr166 | 1.22 | threadStarted.await(); |
387 : | task.cancel(true); | ||
388 : | awaitTermination(t1, MEDIUM_DELAY_MS); | ||
389 : | awaitTermination(t2, MEDIUM_DELAY_MS); | ||
390 : | checkCancelled(task); | ||
391 : | dl | 1.1 | } |
392 : | dl | 1.6 | |
393 : | dl | 1.5 | /** |
394 : | jsr166 | 1.20 | * Cancelling a task causes get in another thread to throw |
395 : | * CancellationException | ||
396 : | dl | 1.5 | */ |
397 : | jsr166 | 1.15 | public void testGet_Cancellation() throws InterruptedException { |
398 : | jsr166 | 1.22 | final CountDownLatch threadStarted = new CountDownLatch(2); |
399 : | final FutureTask task = | ||
400 : | jsr166 | 1.15 | new FutureTask(new CheckedInterruptedCallable<Object>() { |
401 : | jsr166 | 1.16 | public Object realCall() throws InterruptedException { |
402 : | jsr166 | 1.22 | threadStarted.countDown(); |
403 : | dl | 1.25 | delay(LONG_DELAY_MS); |
404 : | jsr166 | 1.16 | return Boolean.TRUE; |
405 : | jsr166 | 1.15 | }}); |
406 : | jsr166 | 1.22 | |
407 : | jsr166 | 1.15 | Thread t1 = new ThreadShouldThrow(CancellationException.class) { |
408 : | public void realRun() throws Exception { | ||
409 : | jsr166 | 1.22 | threadStarted.countDown(); |
410 : | task.get(); | ||
411 : | jsr166 | 1.15 | }}; |
412 : | jsr166 | 1.22 | Thread t2 = new Thread(task); |
413 : | jsr166 | 1.15 | t1.start(); |
414 : | t2.start(); | ||
415 : | jsr166 | 1.22 | threadStarted.await(); |
416 : | task.cancel(true); | ||
417 : | awaitTermination(t1, MEDIUM_DELAY_MS); | ||
418 : | awaitTermination(t2, MEDIUM_DELAY_MS); | ||
419 : | checkCancelled(task); | ||
420 : | dl | 1.1 | } |
421 : | jsr166 | 1.12 | |
422 : | dl | 1.5 | /** |
423 : | dl | 1.6 | * A runtime exception in task causes get to throw ExecutionException |
424 : | dl | 1.5 | */ |
425 : | jsr166 | 1.15 | public void testGet_ExecutionException() throws InterruptedException { |
426 : | jsr166 | 1.22 | final FutureTask task = new FutureTask(new Callable() { |
427 : | jsr166 | 1.16 | public Object call() { |
428 : | jsr166 | 1.15 | return 5/0; |
429 : | }}); | ||
430 : | |||
431 : | jsr166 | 1.22 | task.run(); |
432 : | jsr166 | 1.15 | try { |
433 : | jsr166 | 1.22 | task.get(); |
434 : | jsr166 | 1.17 | shouldThrow(); |
435 : | jsr166 | 1.16 | } catch (ExecutionException success) { |
436 : | jsr166 | 1.15 | assertTrue(success.getCause() instanceof ArithmeticException); |
437 : | jsr166 | 1.22 | checkCompletedAbnormally(task, success.getCause()); |
438 : | dl | 1.1 | } |
439 : | } | ||
440 : | jsr166 | 1.12 | |
441 : | dl | 1.5 | /** |
442 : | jsr166 | 1.20 | * A runtime exception in task causes timed get to throw ExecutionException |
443 : | dl | 1.5 | */ |
444 : | jsr166 | 1.15 | public void testTimedGet_ExecutionException2() throws Exception { |
445 : | jsr166 | 1.22 | final FutureTask task = new FutureTask(new Callable() { |
446 : | jsr166 | 1.16 | public Object call() { |
447 : | jsr166 | 1.15 | return 5/0; |
448 : | }}); | ||
449 : | |||
450 : | jsr166 | 1.22 | task.run(); |
451 : | jsr166 | 1.16 | try { |
452 : | jsr166 | 1.22 | task.get(SHORT_DELAY_MS, MILLISECONDS); |
453 : | jsr166 | 1.17 | shouldThrow(); |
454 : | jsr166 | 1.16 | } catch (ExecutionException success) { |
455 : | jsr166 | 1.15 | assertTrue(success.getCause() instanceof ArithmeticException); |
456 : | jsr166 | 1.22 | checkCompletedAbnormally(task, success.getCause()); |
457 : | jsr166 | 1.15 | } |
458 : | dl | 1.1 | } |
459 : | jsr166 | 1.12 | |
460 : | dl | 1.5 | /** |
461 : | dl | 1.6 | * Interrupting a waiting get causes it to throw InterruptedException |
462 : | dl | 1.5 | */ |
463 : | jsr166 | 1.15 | public void testGet_InterruptedException() throws InterruptedException { |
464 : | jsr166 | 1.22 | final CountDownLatch threadStarted = new CountDownLatch(1); |
465 : | final FutureTask task = new FutureTask(new NoOpCallable()); | ||
466 : | Thread t = newStartedThread(new CheckedInterruptedRunnable() { | ||
467 : | jsr166 | 1.15 | public void realRun() throws Exception { |
468 : | jsr166 | 1.22 | threadStarted.countDown(); |
469 : | task.get(); | ||
470 : | jsr166 | 1.15 | }}); |
471 : | |||
472 : | jsr166 | 1.22 | threadStarted.await(); |
473 : | jsr166 | 1.15 | t.interrupt(); |
474 : | jsr166 | 1.28 | awaitTermination(t); |
475 : | jsr166 | 1.22 | checkNotDone(task); |
476 : | dl | 1.1 | } |
477 : | |||
478 : | dl | 1.5 | /** |
479 : | jsr166 | 1.20 | * Interrupting a waiting timed get causes it to throw InterruptedException |
480 : | dl | 1.5 | */ |
481 : | jsr166 | 1.15 | public void testTimedGet_InterruptedException2() throws InterruptedException { |
482 : | jsr166 | 1.22 | final CountDownLatch threadStarted = new CountDownLatch(1); |
483 : | final FutureTask task = new FutureTask(new NoOpCallable()); | ||
484 : | Thread t = newStartedThread(new CheckedInterruptedRunnable() { | ||
485 : | jsr166 | 1.15 | public void realRun() throws Exception { |
486 : | jsr166 | 1.22 | threadStarted.countDown(); |
487 : | jsr166 | 1.28 | task.get(2*LONG_DELAY_MS, MILLISECONDS); |
488 : | jsr166 | 1.15 | }}); |
489 : | |||
490 : | jsr166 | 1.22 | threadStarted.await(); |
491 : | jsr166 | 1.15 | t.interrupt(); |
492 : | jsr166 | 1.28 | awaitTermination(t); |
493 : | jsr166 | 1.22 | checkNotDone(task); |
494 : | dl | 1.1 | } |
495 : | jsr166 | 1.12 | |
496 : | dl | 1.5 | /** |
497 : | dl | 1.6 | * A timed out timed get throws TimeoutException |
498 : | dl | 1.5 | */ |
499 : | jsr166 | 1.15 | public void testGet_TimeoutException() throws Exception { |
500 : | jsr166 | 1.16 | try { |
501 : | jsr166 | 1.22 | FutureTask task = new FutureTask(new NoOpCallable()); |
502 : | task.get(1, MILLISECONDS); | ||
503 : | jsr166 | 1.17 | shouldThrow(); |
504 : | jsr166 | 1.16 | } catch (TimeoutException success) {} |
505 : | dl | 1.1 | } |
506 : | jsr166 | 1.12 | |
507 : | dl | 1.1 | } |
Doug Lea | ViewVC Help |
Powered by ViewVC 1.0.8 |