ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.37
Committed: Sun Apr 21 06:54:11 2013 UTC (11 years ago) by jsr166
Branch: MAIN
Changes since 1.36: +26 -6 lines
Log Message:
fix rare failure in testTimedGet_Cancellation_interrupt

File Contents

# Content
1 /*
2 * 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 * http://creativecommons.org/publicdomain/zero/1.0/
5 * Other contributors include Andrew Wright, Jeffrey Hayes,
6 * Pat Fisher, Mike Judd.
7 */
8
9 import junit.framework.*;
10 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 import java.util.concurrent.atomic.AtomicInteger;
18 import static java.util.concurrent.TimeUnit.MILLISECONDS;
19 import static java.util.concurrent.TimeUnit.SECONDS;
20 import java.util.*;
21
22 public class FutureTaskTest extends JSR166TestCase {
23
24 public static void main(String[] args) {
25 junit.textui.TestRunner.run(suite());
26 }
27 public static Test suite() {
28 return new TestSuite(FutureTaskTest.class);
29 }
30
31 void checkIsDone(Future<?> f) {
32 assertTrue(f.isDone());
33 assertFalse(f.cancel(false));
34 assertFalse(f.cancel(true));
35 if (f instanceof PublicFutureTask) {
36 PublicFutureTask pf = (PublicFutureTask) f;
37 assertEquals(1, pf.doneCount());
38 assertFalse(pf.runAndReset());
39 assertEquals(1, pf.doneCount());
40 Object r = null; Object exInfo = null;
41 try {
42 r = f.get();
43 } catch (CancellationException t) {
44 exInfo = CancellationException.class;
45 } catch (ExecutionException t) {
46 exInfo = t.getCause();
47 } catch (Throwable t) {
48 threadUnexpectedException(t);
49 }
50
51 // Check that run and runAndReset have no effect.
52 int savedRunCount = pf.runCount();
53 pf.run();
54 pf.runAndReset();
55 assertEquals(savedRunCount, pf.runCount());
56 try {
57 assertSame(r, f.get());
58 } catch (CancellationException t) {
59 assertSame(exInfo, CancellationException.class);
60 } catch (ExecutionException t) {
61 assertSame(exInfo, t.getCause());
62 } catch (Throwable t) {
63 threadUnexpectedException(t);
64 }
65 assertTrue(f.isDone());
66 }
67 }
68
69 void checkNotDone(Future<?> f) {
70 assertFalse(f.isDone());
71 assertFalse(f.isCancelled());
72 if (f instanceof PublicFutureTask) {
73 PublicFutureTask pf = (PublicFutureTask) f;
74 assertEquals(0, pf.doneCount());
75 assertEquals(0, pf.setCount());
76 assertEquals(0, pf.setExceptionCount());
77 }
78 }
79
80 void checkIsRunning(Future<?> f) {
81 checkNotDone(f);
82 if (f instanceof FutureTask) {
83 FutureTask ft = (FutureTask<?>) f;
84 // Check that run methods do nothing
85 ft.run();
86 if (f instanceof PublicFutureTask) {
87 PublicFutureTask pf = (PublicFutureTask) f;
88 int savedRunCount = pf.runCount();
89 pf.run();
90 assertFalse(pf.runAndReset());
91 assertEquals(savedRunCount, pf.runCount());
92 }
93 checkNotDone(f);
94 }
95 }
96
97 <T> void checkCompletedNormally(Future<T> f, T expected) {
98 checkIsDone(f);
99 assertFalse(f.isCancelled());
100
101 try {
102 assertSame(expected, f.get());
103 } catch (Throwable fail) { threadUnexpectedException(fail); }
104 try {
105 assertSame(expected, f.get(5L, SECONDS));
106 } catch (Throwable fail) { threadUnexpectedException(fail); }
107 }
108
109 void checkCancelled(Future<?> f) {
110 checkIsDone(f);
111 assertTrue(f.isCancelled());
112
113 try {
114 f.get();
115 shouldThrow();
116 } catch (CancellationException success) {
117 } catch (Throwable fail) { threadUnexpectedException(fail); }
118
119 try {
120 f.get(5L, SECONDS);
121 shouldThrow();
122 } catch (CancellationException success) {
123 } catch (Throwable fail) { threadUnexpectedException(fail); }
124 }
125
126 void tryToConfuseDoneTask(PublicFutureTask pf) {
127 pf.set(new Object());
128 pf.setException(new Error());
129 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
130 pf.cancel(true);
131 }
132 }
133
134 void checkCompletedAbnormally(Future<?> f, Throwable t) {
135 checkIsDone(f);
136 assertFalse(f.isCancelled());
137
138 try {
139 f.get();
140 shouldThrow();
141 } catch (ExecutionException success) {
142 assertSame(t, success.getCause());
143 } catch (Throwable fail) { threadUnexpectedException(fail); }
144
145 try {
146 f.get(5L, SECONDS);
147 shouldThrow();
148 } catch (ExecutionException success) {
149 assertSame(t, success.getCause());
150 } catch (Throwable fail) { threadUnexpectedException(fail); }
151 }
152
153 /**
154 * Subclass to expose protected methods
155 */
156 static class PublicFutureTask extends FutureTask {
157 private final AtomicInteger runCount;
158 private final AtomicInteger doneCount = new AtomicInteger(0);
159 private final AtomicInteger runAndResetCount = new AtomicInteger(0);
160 private final AtomicInteger setCount = new AtomicInteger(0);
161 private final AtomicInteger setExceptionCount = new AtomicInteger(0);
162 public int runCount() { return runCount.get(); }
163 public int doneCount() { return doneCount.get(); }
164 public int runAndResetCount() { return runAndResetCount.get(); }
165 public int setCount() { return setCount.get(); }
166 public int setExceptionCount() { return setExceptionCount.get(); }
167
168 PublicFutureTask(Runnable runnable) {
169 this(runnable, seven);
170 }
171 PublicFutureTask(Runnable runnable, Object result) {
172 this(runnable, result, new AtomicInteger(0));
173 }
174 private PublicFutureTask(final Runnable runnable, Object result,
175 final AtomicInteger runCount) {
176 super(new Runnable() {
177 public void run() {
178 runCount.getAndIncrement();
179 runnable.run();
180 }}, result);
181 this.runCount = runCount;
182 }
183 PublicFutureTask(Callable callable) {
184 this(callable, new AtomicInteger(0));
185 }
186 private PublicFutureTask(final Callable callable,
187 final AtomicInteger runCount) {
188 super(new Callable() {
189 public Object call() throws Exception {
190 runCount.getAndIncrement();
191 return callable.call();
192 }});
193 this.runCount = runCount;
194 }
195 @Override public void done() {
196 assertTrue(isDone());
197 doneCount.incrementAndGet();
198 super.done();
199 }
200 @Override public boolean runAndReset() {
201 runAndResetCount.incrementAndGet();
202 return super.runAndReset();
203 }
204 @Override public void set(Object x) {
205 setCount.incrementAndGet();
206 super.set(x);
207 }
208 @Override public void setException(Throwable t) {
209 setExceptionCount.incrementAndGet();
210 super.setException(t);
211 }
212 }
213
214 class Counter extends CheckedRunnable {
215 final AtomicInteger count = new AtomicInteger(0);
216 public int get() { return count.get(); }
217 public void realRun() {
218 count.getAndIncrement();
219 }
220 }
221
222 /**
223 * creating a future with a null callable throws NullPointerException
224 */
225 public void testConstructor() {
226 try {
227 new FutureTask(null);
228 shouldThrow();
229 } catch (NullPointerException success) {}
230 }
231
232 /**
233 * creating a future with null runnable throws NullPointerException
234 */
235 public void testConstructor2() {
236 try {
237 new FutureTask(null, Boolean.TRUE);
238 shouldThrow();
239 } catch (NullPointerException success) {}
240 }
241
242 /**
243 * isDone is true when a task completes
244 */
245 public void testIsDone() {
246 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
247 assertFalse(task.isDone());
248 task.run();
249 assertTrue(task.isDone());
250 checkCompletedNormally(task, Boolean.TRUE);
251 assertEquals(1, task.runCount());
252 }
253
254 /**
255 * runAndReset of a non-cancelled task succeeds
256 */
257 public void testRunAndReset() {
258 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
259 for (int i = 0; i < 3; i++) {
260 assertTrue(task.runAndReset());
261 checkNotDone(task);
262 assertEquals(i+1, task.runCount());
263 assertEquals(i+1, task.runAndResetCount());
264 assertEquals(0, task.setCount());
265 assertEquals(0, task.setExceptionCount());
266 }
267 }
268
269 /**
270 * runAndReset after cancellation fails
271 */
272 public void testRunAndResetAfterCancel() {
273 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
274 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
275 assertTrue(task.cancel(mayInterruptIfRunning));
276 for (int i = 0; i < 3; i++) {
277 assertFalse(task.runAndReset());
278 assertEquals(0, task.runCount());
279 assertEquals(i+1, task.runAndResetCount());
280 assertEquals(0, task.setCount());
281 assertEquals(0, task.setExceptionCount());
282 }
283 tryToConfuseDoneTask(task);
284 checkCancelled(task);
285 }
286 }
287
288 /**
289 * setting value causes get to return it
290 */
291 public void testSet() throws Exception {
292 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
293 task.set(one);
294 for (int i = 0; i < 3; i++) {
295 assertSame(one, task.get());
296 assertSame(one, task.get(LONG_DELAY_MS, MILLISECONDS));
297 assertEquals(1, task.setCount());
298 }
299 tryToConfuseDoneTask(task);
300 checkCompletedNormally(task, one);
301 assertEquals(0, task.runCount());
302 }
303
304 /**
305 * setException causes get to throw ExecutionException
306 */
307 public void testSetException_get() throws Exception {
308 Exception nse = new NoSuchElementException();
309 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
310 task.setException(nse);
311
312 try {
313 task.get();
314 shouldThrow();
315 } catch (ExecutionException success) {
316 assertSame(nse, success.getCause());
317 checkCompletedAbnormally(task, nse);
318 }
319
320 try {
321 task.get(LONG_DELAY_MS, MILLISECONDS);
322 shouldThrow();
323 } catch (ExecutionException success) {
324 assertSame(nse, success.getCause());
325 checkCompletedAbnormally(task, nse);
326 }
327
328 assertEquals(1, task.setExceptionCount());
329 assertEquals(0, task.setCount());
330 tryToConfuseDoneTask(task);
331 checkCompletedAbnormally(task, nse);
332 assertEquals(0, task.runCount());
333 }
334
335 /**
336 * cancel(false) before run succeeds
337 */
338 public void testCancelBeforeRun() {
339 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
340 assertTrue(task.cancel(false));
341 task.run();
342 assertEquals(0, task.runCount());
343 assertEquals(0, task.setCount());
344 assertEquals(0, task.setExceptionCount());
345 assertTrue(task.isCancelled());
346 assertTrue(task.isDone());
347 tryToConfuseDoneTask(task);
348 assertEquals(0, task.runCount());
349 checkCancelled(task);
350 }
351
352 /**
353 * cancel(true) before run succeeds
354 */
355 public void testCancelBeforeRun2() {
356 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
357 assertTrue(task.cancel(true));
358 task.run();
359 assertEquals(0, task.runCount());
360 assertEquals(0, task.setCount());
361 assertEquals(0, task.setExceptionCount());
362 assertTrue(task.isCancelled());
363 assertTrue(task.isDone());
364 tryToConfuseDoneTask(task);
365 assertEquals(0, task.runCount());
366 checkCancelled(task);
367 }
368
369 /**
370 * cancel(false) of a completed task fails
371 */
372 public void testCancelAfterRun() {
373 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
374 task.run();
375 assertFalse(task.cancel(false));
376 assertEquals(1, task.runCount());
377 assertEquals(1, task.setCount());
378 assertEquals(0, task.setExceptionCount());
379 tryToConfuseDoneTask(task);
380 checkCompletedNormally(task, Boolean.TRUE);
381 assertEquals(1, task.runCount());
382 }
383
384 /**
385 * cancel(true) of a completed task fails
386 */
387 public void testCancelAfterRun2() {
388 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
389 task.run();
390 assertFalse(task.cancel(true));
391 assertEquals(1, task.runCount());
392 assertEquals(1, task.setCount());
393 assertEquals(0, task.setExceptionCount());
394 tryToConfuseDoneTask(task);
395 checkCompletedNormally(task, Boolean.TRUE);
396 assertEquals(1, task.runCount());
397 }
398
399 /**
400 * cancel(true) interrupts a running task that subsequently succeeds
401 */
402 public void testCancelInterrupt() {
403 final CountDownLatch pleaseCancel = new CountDownLatch(1);
404 final PublicFutureTask task =
405 new PublicFutureTask(new CheckedRunnable() {
406 public void realRun() {
407 pleaseCancel.countDown();
408 try {
409 delay(LONG_DELAY_MS);
410 shouldThrow();
411 } catch (InterruptedException success) {}
412 }});
413
414 Thread t = newStartedThread(task);
415 await(pleaseCancel);
416 assertTrue(task.cancel(true));
417 assertTrue(task.isCancelled());
418 assertTrue(task.isDone());
419 awaitTermination(t);
420 assertEquals(1, task.runCount());
421 assertEquals(1, task.setCount());
422 assertEquals(0, task.setExceptionCount());
423 tryToConfuseDoneTask(task);
424 checkCancelled(task);
425 }
426
427 /**
428 * cancel(true) tries to interrupt a running task, but
429 * Thread.interrupt throws (simulating a restrictive security
430 * manager)
431 */
432 public void testCancelInterrupt_ThrowsSecurityException() {
433 final CountDownLatch pleaseCancel = new CountDownLatch(1);
434 final CountDownLatch cancelled = new CountDownLatch(1);
435 final PublicFutureTask task =
436 new PublicFutureTask(new CheckedRunnable() {
437 public void realRun() {
438 pleaseCancel.countDown();
439 await(cancelled);
440 assertFalse(Thread.interrupted());
441 }});
442
443 final Thread t = new Thread(task) {
444 // Simulate a restrictive security manager.
445 @Override public void interrupt() {
446 throw new SecurityException();
447 }};
448 t.setDaemon(true);
449 t.start();
450
451 await(pleaseCancel);
452 try {
453 task.cancel(true);
454 shouldThrow();
455 } catch (SecurityException expected) {}
456
457 // We failed to deliver the interrupt, but the world retains
458 // its sanity, as if we had done task.cancel(false)
459 assertTrue(task.isCancelled());
460 assertTrue(task.isDone());
461 assertEquals(1, task.runCount());
462 assertEquals(1, task.doneCount());
463 assertEquals(0, task.setCount());
464 assertEquals(0, task.setExceptionCount());
465 cancelled.countDown();
466 awaitTermination(t);
467 assertEquals(1, task.setCount());
468 assertEquals(0, task.setExceptionCount());
469 tryToConfuseDoneTask(task);
470 checkCancelled(task);
471 }
472
473 /**
474 * cancel(true) interrupts a running task that subsequently throws
475 */
476 public void testCancelInterrupt_taskFails() {
477 final CountDownLatch pleaseCancel = new CountDownLatch(1);
478 final PublicFutureTask task =
479 new PublicFutureTask(new Runnable() {
480 public void run() {
481 try {
482 pleaseCancel.countDown();
483 delay(LONG_DELAY_MS);
484 shouldThrow();
485 } catch (Throwable t) {
486 assertTrue(t instanceof InterruptedException);
487 }
488 throw new RuntimeException();
489 }});
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 checkCancelled(task);
501 }
502
503 /**
504 * cancel(false) does not interrupt a running task
505 */
506 public void testCancelNoInterrupt() {
507 final CountDownLatch pleaseCancel = new CountDownLatch(1);
508 final CountDownLatch cancelled = new CountDownLatch(1);
509 final PublicFutureTask task =
510 new PublicFutureTask(new CheckedCallable<Boolean>() {
511 public Boolean realCall() {
512 pleaseCancel.countDown();
513 await(cancelled);
514 assertFalse(Thread.interrupted());
515 return Boolean.TRUE;
516 }});
517
518 Thread t = newStartedThread(task);
519 await(pleaseCancel);
520 assertTrue(task.cancel(false));
521 assertTrue(task.isCancelled());
522 cancelled.countDown();
523 awaitTermination(t);
524 assertEquals(1, task.runCount());
525 assertEquals(1, task.setCount());
526 assertEquals(0, task.setExceptionCount());
527 tryToConfuseDoneTask(task);
528 checkCancelled(task);
529 }
530
531 /**
532 * run in one thread causes get in another thread to retrieve value
533 */
534 public void testGetRun() {
535 final CountDownLatch pleaseRun = new CountDownLatch(2);
536
537 final PublicFutureTask task =
538 new PublicFutureTask(new CheckedCallable<Object>() {
539 public Object realCall() {
540 return two;
541 }});
542
543 Thread t1 = newStartedThread(new CheckedRunnable() {
544 public void realRun() throws Exception {
545 pleaseRun.countDown();
546 assertSame(two, task.get());
547 }});
548
549 Thread t2 = newStartedThread(new CheckedRunnable() {
550 public void realRun() throws Exception {
551 pleaseRun.countDown();
552 assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
553 }});
554
555 await(pleaseRun);
556 checkNotDone(task);
557 assertTrue(t1.isAlive());
558 assertTrue(t2.isAlive());
559 task.run();
560 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 }
569
570 /**
571 * set in one thread causes get in another thread to retrieve value
572 */
573 public void testGetSet() {
574 final CountDownLatch pleaseSet = new CountDownLatch(2);
575
576 final PublicFutureTask task =
577 new PublicFutureTask(new CheckedCallable<Object>() {
578 public Object realCall() throws InterruptedException {
579 return two;
580 }});
581
582 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 public void realRun() throws Exception {
590 pleaseSet.countDown();
591 assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
592 }});
593
594 await(pleaseSet);
595 checkNotDone(task);
596 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 }
607
608 /**
609 * Cancelling a task causes timed get in another thread to throw
610 * CancellationException
611 */
612 public void testTimedGet_Cancellation() {
613 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
636 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
637 public void realRun() throws Exception {
638 pleaseCancel.countDown();
639 task.get();
640 }};
641 Thread t2 = new ThreadShouldThrow(CancellationException.class) {
642 public void realRun() throws Exception {
643 pleaseCancel.countDown();
644 task.get(2*LONG_DELAY_MS, MILLISECONDS);
645 }};
646 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 }
663
664 /**
665 * A runtime exception in task causes get to throw ExecutionException
666 */
667 public void testGet_ExecutionException() throws InterruptedException {
668 final ArithmeticException e = new ArithmeticException();
669 final PublicFutureTask task = new PublicFutureTask(new Callable() {
670 public Object call() {
671 throw e;
672 }});
673
674 task.run();
675 assertEquals(1, task.runCount());
676 assertEquals(0, task.setCount());
677 assertEquals(1, task.setExceptionCount());
678 try {
679 task.get();
680 shouldThrow();
681 } catch (ExecutionException success) {
682 assertSame(e, success.getCause());
683 tryToConfuseDoneTask(task);
684 checkCompletedAbnormally(task, success.getCause());
685 }
686 }
687
688 /**
689 * A runtime exception in task causes timed get to throw ExecutionException
690 */
691 public void testTimedGet_ExecutionException2() throws Exception {
692 final ArithmeticException e = new ArithmeticException();
693 final PublicFutureTask task = new PublicFutureTask(new Callable() {
694 public Object call() {
695 throw e;
696 }});
697
698 task.run();
699 try {
700 task.get(LONG_DELAY_MS, MILLISECONDS);
701 shouldThrow();
702 } catch (ExecutionException success) {
703 assertSame(e, success.getCause());
704 tryToConfuseDoneTask(task);
705 checkCompletedAbnormally(task, success.getCause());
706 }
707 }
708
709 /**
710 * get is interruptible
711 */
712 public void testGet_interruptible() {
713 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
714 final FutureTask task = new FutureTask(new NoOpCallable());
715 Thread t = newStartedThread(new CheckedRunnable() {
716 public void realRun() throws Exception {
717 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 }});
731
732 await(pleaseInterrupt);
733 t.interrupt();
734 awaitTermination(t);
735 checkNotDone(task);
736 }
737
738 /**
739 * timed get is interruptible
740 */
741 public void testTimedGet_interruptible() {
742 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
743 final FutureTask task = new FutureTask(new NoOpCallable());
744 Thread t = newStartedThread(new CheckedRunnable() {
745 public void realRun() throws Exception {
746 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 }});
760
761 await(pleaseInterrupt);
762 t.interrupt();
763 awaitTermination(t);
764 checkNotDone(task);
765 }
766
767 /**
768 * A timed out timed get throws TimeoutException
769 */
770 public void testGet_TimeoutException() throws Exception {
771 FutureTask task = new FutureTask(new NoOpCallable());
772 long startTime = System.nanoTime();
773 try {
774 task.get(timeoutMillis(), MILLISECONDS);
775 shouldThrow();
776 } 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 }
804
805 }