[cvs] / jsr166 / src / test / tck / FutureTaskTest.java Repository:
ViewVC logotype

Annotation of /jsr166/src/test/tck/FutureTaskTest.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.39 - (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 : jsr166 1.39 import java.util.concurrent.ExecutorService;
14 :     import java.util.concurrent.Executors;
15 : jsr166 1.26 import java.util.concurrent.ExecutionException;
16 :     import java.util.concurrent.Future;
17 :     import java.util.concurrent.FutureTask;
18 :     import java.util.concurrent.TimeoutException;
19 : jsr166 1.29 import java.util.concurrent.atomic.AtomicInteger;
20 : jsr166 1.39 import static java.util.concurrent.TimeUnit.*;
21 : dl 1.4 import java.util.*;
22 : dl 1.1
23 : dl 1.4 public class FutureTaskTest extends JSR166TestCase {
24 : dl 1.1
25 :     public static void main(String[] args) {
26 : jsr166 1.19 junit.textui.TestRunner.run(suite());
27 : dl 1.1 }
28 :     public static Test suite() {
29 : jsr166 1.16 return new TestSuite(FutureTaskTest.class);
30 : dl 1.1 }
31 :    
32 : jsr166 1.29 void checkIsDone(Future<?> f) {
33 :     assertTrue(f.isDone());
34 :     assertFalse(f.cancel(false));
35 :     assertFalse(f.cancel(true));
36 :     if (f instanceof PublicFutureTask) {
37 :     PublicFutureTask pf = (PublicFutureTask) f;
38 :     assertEquals(1, pf.doneCount());
39 :     assertFalse(pf.runAndReset());
40 :     assertEquals(1, pf.doneCount());
41 : jsr166 1.37 Object r = null; Object exInfo = null;
42 :     try {
43 :     r = f.get();
44 :     } catch (CancellationException t) {
45 :     exInfo = CancellationException.class;
46 :     } catch (ExecutionException t) {
47 :     exInfo = t.getCause();
48 :     } catch (Throwable t) {
49 :     threadUnexpectedException(t);
50 :     }
51 : jsr166 1.29
52 :     // Check that run and runAndReset have no effect.
53 :     int savedRunCount = pf.runCount();
54 :     pf.run();
55 :     pf.runAndReset();
56 :     assertEquals(savedRunCount, pf.runCount());
57 : jsr166 1.37 try {
58 :     assertSame(r, f.get());
59 :     } catch (CancellationException t) {
60 :     assertSame(exInfo, CancellationException.class);
61 :     } catch (ExecutionException t) {
62 :     assertSame(exInfo, t.getCause());
63 :     } catch (Throwable t) {
64 :     threadUnexpectedException(t);
65 :     }
66 : jsr166 1.29 assertTrue(f.isDone());
67 :     }
68 :     }
69 :    
70 : jsr166 1.22 void checkNotDone(Future<?> f) {
71 :     assertFalse(f.isDone());
72 :     assertFalse(f.isCancelled());
73 : jsr166 1.29 if (f instanceof PublicFutureTask) {
74 :     PublicFutureTask pf = (PublicFutureTask) f;
75 :     assertEquals(0, pf.doneCount());
76 :     assertEquals(0, pf.setCount());
77 :     assertEquals(0, pf.setExceptionCount());
78 :     }
79 :     }
80 :    
81 :     void checkIsRunning(Future<?> f) {
82 :     checkNotDone(f);
83 :     if (f instanceof FutureTask) {
84 :     FutureTask ft = (FutureTask<?>) f;
85 :     // Check that run methods do nothing
86 :     ft.run();
87 : jsr166 1.37 if (f instanceof PublicFutureTask) {
88 :     PublicFutureTask pf = (PublicFutureTask) f;
89 :     int savedRunCount = pf.runCount();
90 :     pf.run();
91 :     assertFalse(pf.runAndReset());
92 :     assertEquals(savedRunCount, pf.runCount());
93 :     }
94 : jsr166 1.29 checkNotDone(f);
95 :     }
96 : jsr166 1.22 }
97 :    
98 :     <T> void checkCompletedNormally(Future<T> f, T expected) {
99 : jsr166 1.29 checkIsDone(f);
100 : jsr166 1.22 assertFalse(f.isCancelled());
101 :    
102 :     try {
103 :     assertSame(expected, f.get());
104 :     } catch (Throwable fail) { threadUnexpectedException(fail); }
105 :     try {
106 :     assertSame(expected, f.get(5L, SECONDS));
107 :     } catch (Throwable fail) { threadUnexpectedException(fail); }
108 :     }
109 :    
110 :     void checkCancelled(Future<?> f) {
111 : jsr166 1.29 checkIsDone(f);
112 : jsr166 1.22 assertTrue(f.isCancelled());
113 :    
114 :     try {
115 :     f.get();
116 :     shouldThrow();
117 :     } catch (CancellationException success) {
118 :     } catch (Throwable fail) { threadUnexpectedException(fail); }
119 :    
120 :     try {
121 :     f.get(5L, SECONDS);
122 :     shouldThrow();
123 :     } catch (CancellationException success) {
124 :     } catch (Throwable fail) { threadUnexpectedException(fail); }
125 : jsr166 1.29 }
126 : jsr166 1.22
127 : jsr166 1.29 void tryToConfuseDoneTask(PublicFutureTask pf) {
128 :     pf.set(new Object());
129 :     pf.setException(new Error());
130 :     for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
131 :     pf.cancel(true);
132 :     }
133 : jsr166 1.22 }
134 :    
135 :     void checkCompletedAbnormally(Future<?> f, Throwable t) {
136 : jsr166 1.29 checkIsDone(f);
137 : jsr166 1.22 assertFalse(f.isCancelled());
138 :    
139 :     try {
140 :     f.get();
141 :     shouldThrow();
142 :     } catch (ExecutionException success) {
143 :     assertSame(t, success.getCause());
144 :     } catch (Throwable fail) { threadUnexpectedException(fail); }
145 :    
146 :     try {
147 :     f.get(5L, SECONDS);
148 :     shouldThrow();
149 :     } catch (ExecutionException success) {
150 :     assertSame(t, success.getCause());
151 :     } catch (Throwable fail) { threadUnexpectedException(fail); }
152 :     }
153 :    
154 : dl 1.4 /**
155 :     * Subclass to expose protected methods
156 :     */
157 : dl 1.7 static class PublicFutureTask extends FutureTask {
158 : jsr166 1.29 private final AtomicInteger runCount;
159 :     private final AtomicInteger doneCount = new AtomicInteger(0);
160 :     private final AtomicInteger runAndResetCount = new AtomicInteger(0);
161 :     private final AtomicInteger setCount = new AtomicInteger(0);
162 :     private final AtomicInteger setExceptionCount = new AtomicInteger(0);
163 :     public int runCount() { return runCount.get(); }
164 :     public int doneCount() { return doneCount.get(); }
165 :     public int runAndResetCount() { return runAndResetCount.get(); }
166 :     public int setCount() { return setCount.get(); }
167 :     public int setExceptionCount() { return setExceptionCount.get(); }
168 :    
169 :     PublicFutureTask(Runnable runnable) {
170 :     this(runnable, seven);
171 :     }
172 :     PublicFutureTask(Runnable runnable, Object result) {
173 :     this(runnable, result, new AtomicInteger(0));
174 :     }
175 :     private PublicFutureTask(final Runnable runnable, Object result,
176 :     final AtomicInteger runCount) {
177 :     super(new Runnable() {
178 : jsr166 1.31 public void run() {
179 :     runCount.getAndIncrement();
180 :     runnable.run();
181 :     }}, result);
182 : jsr166 1.29 this.runCount = runCount;
183 :     }
184 :     PublicFutureTask(Callable callable) {
185 :     this(callable, new AtomicInteger(0));
186 :     }
187 :     private PublicFutureTask(final Callable callable,
188 :     final AtomicInteger runCount) {
189 :     super(new Callable() {
190 :     public Object call() throws Exception {
191 :     runCount.getAndIncrement();
192 :     return callable.call();
193 :     }});
194 :     this.runCount = runCount;
195 :     }
196 : jsr166 1.30 @Override public void done() {
197 : jsr166 1.29 assertTrue(isDone());
198 :     doneCount.incrementAndGet();
199 :     super.done();
200 :     }
201 : jsr166 1.30 @Override public boolean runAndReset() {
202 : jsr166 1.29 runAndResetCount.incrementAndGet();
203 :     return super.runAndReset();
204 :     }
205 : jsr166 1.30 @Override public void set(Object x) {
206 : jsr166 1.29 setCount.incrementAndGet();
207 :     super.set(x);
208 :     }
209 : jsr166 1.30 @Override public void setException(Throwable t) {
210 : jsr166 1.29 setExceptionCount.incrementAndGet();
211 :     super.setException(t);
212 :     }
213 :     }
214 :    
215 :     class Counter extends CheckedRunnable {
216 :     final AtomicInteger count = new AtomicInteger(0);
217 :     public int get() { return count.get(); }
218 :     public void realRun() {
219 :     count.getAndIncrement();
220 :     }
221 : dl 1.4 }
222 : dl 1.1
223 : dl 1.5 /**
224 : jsr166 1.29 * creating a future with a null callable throws NullPointerException
225 : dl 1.5 */
226 :     public void testConstructor() {
227 : dl 1.3 try {
228 : jsr166 1.29 new FutureTask(null);
229 : jsr166 1.17 shouldThrow();
230 : jsr166 1.15 } catch (NullPointerException success) {}
231 : dl 1.3 }
232 :    
233 : dl 1.5 /**
234 : jsr166 1.29 * creating a future with null runnable throws NullPointerException
235 : dl 1.5 */
236 :     public void testConstructor2() {
237 : dl 1.3 try {
238 : jsr166 1.29 new FutureTask(null, Boolean.TRUE);
239 : jsr166 1.17 shouldThrow();
240 : jsr166 1.15 } catch (NullPointerException success) {}
241 : dl 1.3 }
242 :    
243 : dl 1.5 /**
244 : dl 1.6 * isDone is true when a task completes
245 : dl 1.5 */
246 :     public void testIsDone() {
247 : jsr166 1.29 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
248 :     assertFalse(task.isDone());
249 : jsr166 1.16 task.run();
250 :     assertTrue(task.isDone());
251 : jsr166 1.22 checkCompletedNormally(task, Boolean.TRUE);
252 : jsr166 1.29 assertEquals(1, task.runCount());
253 : dl 1.4 }
254 :    
255 : dl 1.5 /**
256 : dl 1.9 * runAndReset of a non-cancelled task succeeds
257 : dl 1.5 */
258 : dl 1.9 public void testRunAndReset() {
259 : dl 1.7 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
260 : jsr166 1.29 for (int i = 0; i < 3; i++) {
261 :     assertTrue(task.runAndReset());
262 :     checkNotDone(task);
263 :     assertEquals(i+1, task.runCount());
264 :     assertEquals(i+1, task.runAndResetCount());
265 :     assertEquals(0, task.setCount());
266 :     assertEquals(0, task.setExceptionCount());
267 :     }
268 : dl 1.4 }
269 :    
270 : dl 1.5 /**
271 : dl 1.9 * runAndReset after cancellation fails
272 : dl 1.5 */
273 : jsr166 1.29 public void testRunAndResetAfterCancel() {
274 :     for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
275 :     PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
276 :     assertTrue(task.cancel(mayInterruptIfRunning));
277 :     for (int i = 0; i < 3; i++) {
278 :     assertFalse(task.runAndReset());
279 :     assertEquals(0, task.runCount());
280 :     assertEquals(i+1, task.runAndResetCount());
281 :     assertEquals(0, task.setCount());
282 :     assertEquals(0, task.setExceptionCount());
283 :     }
284 :     tryToConfuseDoneTask(task);
285 :     checkCancelled(task);
286 :     }
287 : dl 1.4 }
288 :    
289 : dl 1.5 /**
290 : dl 1.11 * setting value causes get to return it
291 : dl 1.5 */
292 : jsr166 1.15 public void testSet() throws Exception {
293 : dl 1.7 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
294 : dl 1.4 task.set(one);
295 : jsr166 1.29 for (int i = 0; i < 3; i++) {
296 :     assertSame(one, task.get());
297 :     assertSame(one, task.get(LONG_DELAY_MS, MILLISECONDS));
298 :     assertEquals(1, task.setCount());
299 :     }
300 :     tryToConfuseDoneTask(task);
301 : jsr166 1.22 checkCompletedNormally(task, one);
302 : jsr166 1.29 assertEquals(0, task.runCount());
303 : dl 1.4 }
304 :    
305 : dl 1.5 /**
306 : dl 1.6 * setException causes get to throw ExecutionException
307 : dl 1.5 */
308 : jsr166 1.29 public void testSetException_get() throws Exception {
309 : dl 1.4 Exception nse = new NoSuchElementException();
310 : dl 1.7 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
311 : dl 1.4 task.setException(nse);
312 : jsr166 1.29
313 :     try {
314 :     task.get();
315 :     shouldThrow();
316 :     } catch (ExecutionException success) {
317 :     assertSame(nse, success.getCause());
318 :     checkCompletedAbnormally(task, nse);
319 :     }
320 :    
321 : dl 1.4 try {
322 : jsr166 1.29 task.get(LONG_DELAY_MS, MILLISECONDS);
323 : jsr166 1.17 shouldThrow();
324 : jsr166 1.15 } catch (ExecutionException success) {
325 : jsr166 1.29 assertSame(nse, success.getCause());
326 : jsr166 1.22 checkCompletedAbnormally(task, nse);
327 : dl 1.4 }
328 : jsr166 1.29
329 :     assertEquals(1, task.setExceptionCount());
330 :     assertEquals(0, task.setCount());
331 :     tryToConfuseDoneTask(task);
332 :     checkCompletedAbnormally(task, nse);
333 :     assertEquals(0, task.runCount());
334 : dl 1.4 }
335 :    
336 : dl 1.5 /**
337 : jsr166 1.29 * cancel(false) before run succeeds
338 : dl 1.5 */
339 : dl 1.1 public void testCancelBeforeRun() {
340 : jsr166 1.29 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
341 : dl 1.1 assertTrue(task.cancel(false));
342 : jsr166 1.16 task.run();
343 : jsr166 1.32 assertEquals(0, task.runCount());
344 : jsr166 1.29 assertEquals(0, task.setCount());
345 :     assertEquals(0, task.setExceptionCount());
346 : jsr166 1.32 assertTrue(task.isCancelled());
347 :     assertTrue(task.isDone());
348 : jsr166 1.29 tryToConfuseDoneTask(task);
349 : jsr166 1.32 assertEquals(0, task.runCount());
350 : jsr166 1.22 checkCancelled(task);
351 : dl 1.1 }
352 :    
353 : dl 1.5 /**
354 : jsr166 1.29 * cancel(true) before run succeeds
355 : dl 1.5 */
356 : dl 1.1 public void testCancelBeforeRun2() {
357 : jsr166 1.29 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
358 : dl 1.1 assertTrue(task.cancel(true));
359 : jsr166 1.16 task.run();
360 : jsr166 1.32 assertEquals(0, task.runCount());
361 : jsr166 1.29 assertEquals(0, task.setCount());
362 :     assertEquals(0, task.setExceptionCount());
363 : jsr166 1.32 assertTrue(task.isCancelled());
364 :     assertTrue(task.isDone());
365 : jsr166 1.29 tryToConfuseDoneTask(task);
366 : jsr166 1.32 assertEquals(0, task.runCount());
367 : jsr166 1.22 checkCancelled(task);
368 : dl 1.1 }
369 :    
370 : dl 1.5 /**
371 : jsr166 1.29 * cancel(false) of a completed task fails
372 : dl 1.5 */
373 : dl 1.1 public void testCancelAfterRun() {
374 : jsr166 1.29 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
375 : jsr166 1.16 task.run();
376 : dl 1.1 assertFalse(task.cancel(false));
377 : jsr166 1.32 assertEquals(1, task.runCount());
378 : jsr166 1.29 assertEquals(1, task.setCount());
379 :     assertEquals(0, task.setExceptionCount());
380 :     tryToConfuseDoneTask(task);
381 :     checkCompletedNormally(task, Boolean.TRUE);
382 :     assertEquals(1, task.runCount());
383 :     }
384 :    
385 :     /**
386 :     * cancel(true) of a completed task fails
387 :     */
388 :     public void testCancelAfterRun2() {
389 :     PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
390 :     task.run();
391 :     assertFalse(task.cancel(true));
392 : jsr166 1.32 assertEquals(1, task.runCount());
393 : jsr166 1.29 assertEquals(1, task.setCount());
394 :     assertEquals(0, task.setExceptionCount());
395 :     tryToConfuseDoneTask(task);
396 : jsr166 1.22 checkCompletedNormally(task, Boolean.TRUE);
397 : jsr166 1.29 assertEquals(1, task.runCount());
398 : dl 1.1 }
399 :    
400 : dl 1.5 /**
401 : jsr166 1.29 * cancel(true) interrupts a running task that subsequently succeeds
402 : dl 1.5 */
403 : jsr166 1.29 public void testCancelInterrupt() {
404 :     final CountDownLatch pleaseCancel = new CountDownLatch(1);
405 :     final PublicFutureTask task =
406 :     new PublicFutureTask(new CheckedRunnable() {
407 :     public void realRun() {
408 :     pleaseCancel.countDown();
409 :     try {
410 :     delay(LONG_DELAY_MS);
411 :     shouldThrow();
412 :     } catch (InterruptedException success) {}
413 : jsr166 1.15 }});
414 :    
415 : jsr166 1.22 Thread t = newStartedThread(task);
416 : jsr166 1.29 await(pleaseCancel);
417 : jsr166 1.15 assertTrue(task.cancel(true));
418 : jsr166 1.29 assertTrue(task.isCancelled());
419 : jsr166 1.32 assertTrue(task.isDone());
420 : jsr166 1.29 awaitTermination(t);
421 :     assertEquals(1, task.runCount());
422 :     assertEquals(1, task.setCount());
423 :     assertEquals(0, task.setExceptionCount());
424 :     tryToConfuseDoneTask(task);
425 : jsr166 1.22 checkCancelled(task);
426 : jsr166 1.29 }
427 :    
428 :     /**
429 : jsr166 1.33 * cancel(true) tries to interrupt a running task, but
430 :     * Thread.interrupt throws (simulating a restrictive security
431 :     * manager)
432 : jsr166 1.32 */
433 :     public void testCancelInterrupt_ThrowsSecurityException() {
434 :     final CountDownLatch pleaseCancel = new CountDownLatch(1);
435 :     final CountDownLatch cancelled = new CountDownLatch(1);
436 :     final PublicFutureTask task =
437 :     new PublicFutureTask(new CheckedRunnable() {
438 :     public void realRun() {
439 :     pleaseCancel.countDown();
440 :     await(cancelled);
441 :     assertFalse(Thread.interrupted());
442 :     }});
443 :    
444 : jsr166 1.33 final Thread t = new Thread(task) {
445 :     // Simulate a restrictive security manager.
446 :     @Override public void interrupt() {
447 :     throw new SecurityException();
448 :     }};
449 :     t.setDaemon(true);
450 :     t.start();
451 :    
452 : jsr166 1.32 await(pleaseCancel);
453 :     try {
454 : jsr166 1.33 task.cancel(true);
455 :     shouldThrow();
456 :     } catch (SecurityException expected) {}
457 :    
458 :     // We failed to deliver the interrupt, but the world retains
459 :     // its sanity, as if we had done task.cancel(false)
460 : jsr166 1.32 assertTrue(task.isCancelled());
461 :     assertTrue(task.isDone());
462 :     assertEquals(1, task.runCount());
463 :     assertEquals(1, task.doneCount());
464 :     assertEquals(0, task.setCount());
465 :     assertEquals(0, task.setExceptionCount());
466 :     cancelled.countDown();
467 :     awaitTermination(t);
468 :     assertEquals(1, task.setCount());
469 :     assertEquals(0, task.setExceptionCount());
470 :     tryToConfuseDoneTask(task);
471 :     checkCancelled(task);
472 :     }
473 :    
474 :     /**
475 : jsr166 1.29 * cancel(true) interrupts a running task that subsequently throws
476 :     */
477 :     public void testCancelInterrupt_taskFails() {
478 :     final CountDownLatch pleaseCancel = new CountDownLatch(1);
479 :     final PublicFutureTask task =
480 :     new PublicFutureTask(new Runnable() {
481 :     public void run() {
482 :     try {
483 :     pleaseCancel.countDown();
484 :     delay(LONG_DELAY_MS);
485 : jsr166 1.38 threadShouldThrow();
486 :     } catch (InterruptedException success) {
487 :     } catch (Throwable t) { threadUnexpectedException(t); }
488 : jsr166 1.35 throw new RuntimeException();
489 : jsr166 1.29 }});
490 :    
491 :     Thread t = newStartedThread(task);
492 :     await(pleaseCancel);
493 :     assertTrue(task.cancel(true));
494 :     assertTrue(task.isCancelled());
495 :     awaitTermination(t);
496 :     assertEquals(1, task.runCount());
497 :     assertEquals(0, task.setCount());
498 :     assertEquals(1, task.setExceptionCount());
499 :     tryToConfuseDoneTask(task);
500 : jsr166 1.22 checkCancelled(task);
501 : dl 1.1 }
502 :    
503 : dl 1.5 /**
504 : dl 1.6 * cancel(false) does not interrupt a running task
505 : dl 1.5 */
506 : jsr166 1.29 public void testCancelNoInterrupt() {
507 :     final CountDownLatch pleaseCancel = new CountDownLatch(1);
508 : jsr166 1.22 final CountDownLatch cancelled = new CountDownLatch(1);
509 : jsr166 1.29 final PublicFutureTask task =
510 :     new PublicFutureTask(new CheckedCallable<Boolean>() {
511 :     public Boolean realCall() {
512 :     pleaseCancel.countDown();
513 :     await(cancelled);
514 : jsr166 1.22 assertFalse(Thread.interrupted());
515 : dl 1.1 return Boolean.TRUE;
516 : jsr166 1.15 }});
517 :    
518 : jsr166 1.22 Thread t = newStartedThread(task);
519 : jsr166 1.29 await(pleaseCancel);
520 : jsr166 1.15 assertTrue(task.cancel(false));
521 : jsr166 1.29 assertTrue(task.isCancelled());
522 : jsr166 1.22 cancelled.countDown();
523 : jsr166 1.29 awaitTermination(t);
524 :     assertEquals(1, task.runCount());
525 :     assertEquals(1, task.setCount());
526 :     assertEquals(0, task.setExceptionCount());
527 :     tryToConfuseDoneTask(task);
528 : jsr166 1.22 checkCancelled(task);
529 : dl 1.1 }
530 :    
531 : dl 1.5 /**
532 : jsr166 1.23 * run in one thread causes get in another thread to retrieve value
533 : dl 1.5 */
534 : jsr166 1.29 public void testGetRun() {
535 :     final CountDownLatch pleaseRun = new CountDownLatch(2);
536 : jsr166 1.23
537 :     final PublicFutureTask task =
538 :     new PublicFutureTask(new CheckedCallable<Object>() {
539 : jsr166 1.29 public Object realCall() {
540 :     return two;
541 : jsr166 1.23 }});
542 :    
543 : jsr166 1.29 Thread t1 = newStartedThread(new CheckedRunnable() {
544 : jsr166 1.23 public void realRun() throws Exception {
545 : jsr166 1.29 pleaseRun.countDown();
546 :     assertSame(two, task.get());
547 : jsr166 1.23 }});
548 :    
549 : jsr166 1.29 Thread t2 = newStartedThread(new CheckedRunnable() {
550 : jsr166 1.15 public void realRun() throws Exception {
551 : jsr166 1.29 pleaseRun.countDown();
552 :     assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
553 : jsr166 1.15 }});
554 : jsr166 1.12
555 : jsr166 1.29 await(pleaseRun);
556 : jsr166 1.23 checkNotDone(task);
557 : jsr166 1.29 assertTrue(t1.isAlive());
558 :     assertTrue(t2.isAlive());
559 : jsr166 1.22 task.run();
560 : jsr166 1.29 checkCompletedNormally(task, two);
561 :     assertEquals(1, task.runCount());
562 :     assertEquals(1, task.setCount());
563 :     assertEquals(0, task.setExceptionCount());
564 :     awaitTermination(t1);
565 :     awaitTermination(t2);
566 :     tryToConfuseDoneTask(task);
567 :     checkCompletedNormally(task, two);
568 : dl 1.1 }
569 :    
570 : dl 1.5 /**
571 : jsr166 1.29 * set in one thread causes get in another thread to retrieve value
572 : jsr166 1.23 */
573 : jsr166 1.29 public void testGetSet() {
574 :     final CountDownLatch pleaseSet = new CountDownLatch(2);
575 : jsr166 1.23
576 :     final PublicFutureTask task =
577 :     new PublicFutureTask(new CheckedCallable<Object>() {
578 :     public Object realCall() throws InterruptedException {
579 : jsr166 1.29 return two;
580 : jsr166 1.23 }});
581 :    
582 : jsr166 1.29 Thread t1 = newStartedThread(new CheckedRunnable() {
583 :     public void realRun() throws Exception {
584 :     pleaseSet.countDown();
585 :     assertSame(two, task.get());
586 :     }});
587 :    
588 :     Thread t2 = newStartedThread(new CheckedRunnable() {
589 : jsr166 1.23 public void realRun() throws Exception {
590 : jsr166 1.29 pleaseSet.countDown();
591 :     assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
592 : jsr166 1.23 }});
593 :    
594 : jsr166 1.29 await(pleaseSet);
595 : jsr166 1.23 checkNotDone(task);
596 : jsr166 1.29 assertTrue(t1.isAlive());
597 :     assertTrue(t2.isAlive());
598 :     task.set(two);
599 :     assertEquals(0, task.runCount());
600 :     assertEquals(1, task.setCount());
601 :     assertEquals(0, task.setExceptionCount());
602 :     tryToConfuseDoneTask(task);
603 :     checkCompletedNormally(task, two);
604 :     awaitTermination(t1);
605 :     awaitTermination(t2);
606 : jsr166 1.23 }
607 :    
608 :     /**
609 : jsr166 1.21 * Cancelling a task causes timed get in another thread to throw
610 :     * CancellationException
611 : dl 1.5 */
612 : jsr166 1.29 public void testTimedGet_Cancellation() {
613 : jsr166 1.36 testTimedGet_Cancellation(false);
614 :     }
615 :     public void testTimedGet_Cancellation_interrupt() {
616 :     testTimedGet_Cancellation(true);
617 :     }
618 :     public void testTimedGet_Cancellation(final boolean mayInterruptIfRunning) {
619 :     final CountDownLatch pleaseCancel = new CountDownLatch(3);
620 :     final CountDownLatch cancelled = new CountDownLatch(1);
621 :     final Callable<Object> callable =
622 :     new CheckedCallable<Object>() {
623 :     public Object realCall() throws InterruptedException {
624 :     pleaseCancel.countDown();
625 :     if (mayInterruptIfRunning) {
626 :     try {
627 :     delay(2*LONG_DELAY_MS);
628 :     } catch (InterruptedException success) {}
629 :     } else {
630 :     await(cancelled);
631 :     }
632 :     return two;
633 :     }};
634 :     final PublicFutureTask task = new PublicFutureTask(callable);
635 : jsr166 1.29
636 : jsr166 1.36 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
637 : jsr166 1.29 public void realRun() throws Exception {
638 :     pleaseCancel.countDown();
639 :     task.get();
640 :     }};
641 : jsr166 1.36 Thread t2 = new ThreadShouldThrow(CancellationException.class) {
642 : jsr166 1.29 public void realRun() throws Exception {
643 :     pleaseCancel.countDown();
644 :     task.get(2*LONG_DELAY_MS, MILLISECONDS);
645 :     }};
646 : jsr166 1.36 t1.start();
647 :     t2.start();
648 :     Thread t3 = newStartedThread(task);
649 :     await(pleaseCancel);
650 :     checkIsRunning(task);
651 :     task.cancel(mayInterruptIfRunning);
652 :     checkCancelled(task);
653 :     awaitTermination(t1);
654 :     awaitTermination(t2);
655 :     cancelled.countDown();
656 :     awaitTermination(t3);
657 :     assertEquals(1, task.runCount());
658 :     assertEquals(1, task.setCount());
659 :     assertEquals(0, task.setExceptionCount());
660 :     tryToConfuseDoneTask(task);
661 :     checkCancelled(task);
662 : dl 1.1 }
663 : jsr166 1.12
664 : dl 1.5 /**
665 : dl 1.6 * A runtime exception in task causes get to throw ExecutionException
666 : dl 1.5 */
667 : jsr166 1.15 public void testGet_ExecutionException() throws InterruptedException {
668 : jsr166 1.29 final ArithmeticException e = new ArithmeticException();
669 :     final PublicFutureTask task = new PublicFutureTask(new Callable() {
670 : jsr166 1.16 public Object call() {
671 : jsr166 1.29 throw e;
672 : jsr166 1.15 }});
673 :    
674 : jsr166 1.22 task.run();
675 : jsr166 1.29 assertEquals(1, task.runCount());
676 :     assertEquals(0, task.setCount());
677 :     assertEquals(1, task.setExceptionCount());
678 : jsr166 1.15 try {
679 : jsr166 1.22 task.get();
680 : jsr166 1.17 shouldThrow();
681 : jsr166 1.16 } catch (ExecutionException success) {
682 : jsr166 1.29 assertSame(e, success.getCause());
683 :     tryToConfuseDoneTask(task);
684 : jsr166 1.22 checkCompletedAbnormally(task, success.getCause());
685 : dl 1.1 }
686 :     }
687 : jsr166 1.12
688 : dl 1.5 /**
689 : jsr166 1.20 * A runtime exception in task causes timed get to throw ExecutionException
690 : dl 1.5 */
691 : jsr166 1.15 public void testTimedGet_ExecutionException2() throws Exception {
692 : jsr166 1.29 final ArithmeticException e = new ArithmeticException();
693 :     final PublicFutureTask task = new PublicFutureTask(new Callable() {
694 : jsr166 1.16 public Object call() {
695 : jsr166 1.29 throw e;
696 : jsr166 1.15 }});
697 :    
698 : jsr166 1.22 task.run();
699 : jsr166 1.16 try {
700 : jsr166 1.29 task.get(LONG_DELAY_MS, MILLISECONDS);
701 : jsr166 1.17 shouldThrow();
702 : jsr166 1.16 } catch (ExecutionException success) {
703 : jsr166 1.29 assertSame(e, success.getCause());
704 :     tryToConfuseDoneTask(task);
705 : jsr166 1.22 checkCompletedAbnormally(task, success.getCause());
706 : jsr166 1.15 }
707 : dl 1.1 }
708 : jsr166 1.12
709 : dl 1.5 /**
710 : jsr166 1.29 * get is interruptible
711 : dl 1.5 */
712 : jsr166 1.29 public void testGet_interruptible() {
713 :     final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
714 : jsr166 1.22 final FutureTask task = new FutureTask(new NoOpCallable());
715 : jsr166 1.29 Thread t = newStartedThread(new CheckedRunnable() {
716 : jsr166 1.15 public void realRun() throws Exception {
717 : jsr166 1.29 Thread.currentThread().interrupt();
718 :     try {
719 :     task.get();
720 :     shouldThrow();
721 :     } catch (InterruptedException success) {}
722 :     assertFalse(Thread.interrupted());
723 :    
724 :     pleaseInterrupt.countDown();
725 :     try {
726 :     task.get();
727 :     shouldThrow();
728 :     } catch (InterruptedException success) {}
729 :     assertFalse(Thread.interrupted());
730 : jsr166 1.15 }});
731 :    
732 : jsr166 1.29 await(pleaseInterrupt);
733 : jsr166 1.15 t.interrupt();
734 : jsr166 1.28 awaitTermination(t);
735 : jsr166 1.22 checkNotDone(task);
736 : dl 1.1 }
737 :    
738 : dl 1.5 /**
739 : jsr166 1.29 * timed get is interruptible
740 : dl 1.5 */
741 : jsr166 1.29 public void testTimedGet_interruptible() {
742 :     final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
743 : jsr166 1.22 final FutureTask task = new FutureTask(new NoOpCallable());
744 : jsr166 1.29 Thread t = newStartedThread(new CheckedRunnable() {
745 : jsr166 1.15 public void realRun() throws Exception {
746 : jsr166 1.29 Thread.currentThread().interrupt();
747 :     try {
748 :     task.get(2*LONG_DELAY_MS, MILLISECONDS);
749 :     shouldThrow();
750 :     } catch (InterruptedException success) {}
751 :     assertFalse(Thread.interrupted());
752 :    
753 :     pleaseInterrupt.countDown();
754 :     try {
755 :     task.get(2*LONG_DELAY_MS, MILLISECONDS);
756 :     shouldThrow();
757 :     } catch (InterruptedException success) {}
758 :     assertFalse(Thread.interrupted());
759 : jsr166 1.15 }});
760 :    
761 : jsr166 1.29 await(pleaseInterrupt);
762 : jsr166 1.15 t.interrupt();
763 : jsr166 1.28 awaitTermination(t);
764 : jsr166 1.22 checkNotDone(task);
765 : dl 1.1 }
766 : jsr166 1.12
767 : dl 1.5 /**
768 : dl 1.6 * A timed out timed get throws TimeoutException
769 : dl 1.5 */
770 : jsr166 1.15 public void testGet_TimeoutException() throws Exception {
771 : jsr166 1.29 FutureTask task = new FutureTask(new NoOpCallable());
772 :     long startTime = System.nanoTime();
773 : jsr166 1.16 try {
774 : jsr166 1.29 task.get(timeoutMillis(), MILLISECONDS);
775 : jsr166 1.17 shouldThrow();
776 : jsr166 1.29 } catch (TimeoutException success) {
777 :     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
778 :     }
779 :     }
780 :    
781 :     /**
782 :     * timed get with null TimeUnit throws NullPointerException
783 :     */
784 :     public void testGet_NullTimeUnit() throws Exception {
785 :     FutureTask task = new FutureTask(new NoOpCallable());
786 :     long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
787 :    
788 :     for (long timeout : timeouts) {
789 :     try {
790 :     task.get(timeout, null);
791 :     shouldThrow();
792 :     } catch (NullPointerException success) {}
793 :     }
794 :    
795 :     task.run();
796 :    
797 :     for (long timeout : timeouts) {
798 :     try {
799 :     task.get(timeout, null);
800 :     shouldThrow();
801 :     } catch (NullPointerException success) {}
802 :     }
803 : dl 1.1 }
804 : jsr166 1.12
805 : jsr166 1.39 /**
806 :     * timed get with most negative timeout works correctly (i.e. no
807 :     * underflow bug)
808 :     */
809 :     public void testGet_NegativeInfinityTimeout() throws Exception {
810 :     final ExecutorService pool = Executors.newFixedThreadPool(10);
811 :     final Runnable nop = new Runnable() { public void run() {}};
812 :     final FutureTask<Void> task = new FutureTask<>(nop, null);
813 :     final List<Future<?>> futures = new ArrayList<>();
814 :     Runnable r = new Runnable() { public void run() {
815 :     for (long timeout : new long[] { 0L, -1L, Long.MIN_VALUE }) {
816 :     try {
817 :     task.get(timeout, NANOSECONDS);
818 :     shouldThrow();
819 :     } catch (TimeoutException success) {
820 :     } catch (Throwable fail) {threadUnexpectedException(fail);}}}};
821 :     for (int i = 0; i < 10; i++)
822 :     futures.add(pool.submit(r));
823 :     try {
824 :     joinPool(pool);
825 :     for (Future<?> future : futures)
826 :     checkCompletedNormally(future, null);
827 :     } finally {
828 :     task.run(); // last resort to help terminate
829 :     }
830 :     }
831 :    
832 : dl 1.1 }

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8