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