ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.38
Committed: Wed Jun 19 05:54:45 2013 UTC (10 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.37: +3 -4 lines
Log Message:
improve testCancelInterrupt_taskFails

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 threadShouldThrow();
485 } catch (InterruptedException success) {
486 } catch (Throwable t) { threadUnexpectedException(t); }
487 throw new RuntimeException();
488 }});
489
490 Thread t = newStartedThread(task);
491 await(pleaseCancel);
492 assertTrue(task.cancel(true));
493 assertTrue(task.isCancelled());
494 awaitTermination(t);
495 assertEquals(1, task.runCount());
496 assertEquals(0, task.setCount());
497 assertEquals(1, task.setExceptionCount());
498 tryToConfuseDoneTask(task);
499 checkCancelled(task);
500 }
501
502 /**
503 * cancel(false) does not interrupt a running task
504 */
505 public void testCancelNoInterrupt() {
506 final CountDownLatch pleaseCancel = new CountDownLatch(1);
507 final CountDownLatch cancelled = new CountDownLatch(1);
508 final PublicFutureTask task =
509 new PublicFutureTask(new CheckedCallable<Boolean>() {
510 public Boolean realCall() {
511 pleaseCancel.countDown();
512 await(cancelled);
513 assertFalse(Thread.interrupted());
514 return Boolean.TRUE;
515 }});
516
517 Thread t = newStartedThread(task);
518 await(pleaseCancel);
519 assertTrue(task.cancel(false));
520 assertTrue(task.isCancelled());
521 cancelled.countDown();
522 awaitTermination(t);
523 assertEquals(1, task.runCount());
524 assertEquals(1, task.setCount());
525 assertEquals(0, task.setExceptionCount());
526 tryToConfuseDoneTask(task);
527 checkCancelled(task);
528 }
529
530 /**
531 * run in one thread causes get in another thread to retrieve value
532 */
533 public void testGetRun() {
534 final CountDownLatch pleaseRun = new CountDownLatch(2);
535
536 final PublicFutureTask task =
537 new PublicFutureTask(new CheckedCallable<Object>() {
538 public Object realCall() {
539 return two;
540 }});
541
542 Thread t1 = newStartedThread(new CheckedRunnable() {
543 public void realRun() throws Exception {
544 pleaseRun.countDown();
545 assertSame(two, task.get());
546 }});
547
548 Thread t2 = newStartedThread(new CheckedRunnable() {
549 public void realRun() throws Exception {
550 pleaseRun.countDown();
551 assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
552 }});
553
554 await(pleaseRun);
555 checkNotDone(task);
556 assertTrue(t1.isAlive());
557 assertTrue(t2.isAlive());
558 task.run();
559 checkCompletedNormally(task, two);
560 assertEquals(1, task.runCount());
561 assertEquals(1, task.setCount());
562 assertEquals(0, task.setExceptionCount());
563 awaitTermination(t1);
564 awaitTermination(t2);
565 tryToConfuseDoneTask(task);
566 checkCompletedNormally(task, two);
567 }
568
569 /**
570 * set in one thread causes get in another thread to retrieve value
571 */
572 public void testGetSet() {
573 final CountDownLatch pleaseSet = new CountDownLatch(2);
574
575 final PublicFutureTask task =
576 new PublicFutureTask(new CheckedCallable<Object>() {
577 public Object realCall() throws InterruptedException {
578 return two;
579 }});
580
581 Thread t1 = newStartedThread(new CheckedRunnable() {
582 public void realRun() throws Exception {
583 pleaseSet.countDown();
584 assertSame(two, task.get());
585 }});
586
587 Thread t2 = newStartedThread(new CheckedRunnable() {
588 public void realRun() throws Exception {
589 pleaseSet.countDown();
590 assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
591 }});
592
593 await(pleaseSet);
594 checkNotDone(task);
595 assertTrue(t1.isAlive());
596 assertTrue(t2.isAlive());
597 task.set(two);
598 assertEquals(0, task.runCount());
599 assertEquals(1, task.setCount());
600 assertEquals(0, task.setExceptionCount());
601 tryToConfuseDoneTask(task);
602 checkCompletedNormally(task, two);
603 awaitTermination(t1);
604 awaitTermination(t2);
605 }
606
607 /**
608 * Cancelling a task causes timed get in another thread to throw
609 * CancellationException
610 */
611 public void testTimedGet_Cancellation() {
612 testTimedGet_Cancellation(false);
613 }
614 public void testTimedGet_Cancellation_interrupt() {
615 testTimedGet_Cancellation(true);
616 }
617 public void testTimedGet_Cancellation(final boolean mayInterruptIfRunning) {
618 final CountDownLatch pleaseCancel = new CountDownLatch(3);
619 final CountDownLatch cancelled = new CountDownLatch(1);
620 final Callable<Object> callable =
621 new CheckedCallable<Object>() {
622 public Object realCall() throws InterruptedException {
623 pleaseCancel.countDown();
624 if (mayInterruptIfRunning) {
625 try {
626 delay(2*LONG_DELAY_MS);
627 } catch (InterruptedException success) {}
628 } else {
629 await(cancelled);
630 }
631 return two;
632 }};
633 final PublicFutureTask task = new PublicFutureTask(callable);
634
635 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
636 public void realRun() throws Exception {
637 pleaseCancel.countDown();
638 task.get();
639 }};
640 Thread t2 = new ThreadShouldThrow(CancellationException.class) {
641 public void realRun() throws Exception {
642 pleaseCancel.countDown();
643 task.get(2*LONG_DELAY_MS, MILLISECONDS);
644 }};
645 t1.start();
646 t2.start();
647 Thread t3 = newStartedThread(task);
648 await(pleaseCancel);
649 checkIsRunning(task);
650 task.cancel(mayInterruptIfRunning);
651 checkCancelled(task);
652 awaitTermination(t1);
653 awaitTermination(t2);
654 cancelled.countDown();
655 awaitTermination(t3);
656 assertEquals(1, task.runCount());
657 assertEquals(1, task.setCount());
658 assertEquals(0, task.setExceptionCount());
659 tryToConfuseDoneTask(task);
660 checkCancelled(task);
661 }
662
663 /**
664 * A runtime exception in task causes get to throw ExecutionException
665 */
666 public void testGet_ExecutionException() throws InterruptedException {
667 final ArithmeticException e = new ArithmeticException();
668 final PublicFutureTask task = new PublicFutureTask(new Callable() {
669 public Object call() {
670 throw e;
671 }});
672
673 task.run();
674 assertEquals(1, task.runCount());
675 assertEquals(0, task.setCount());
676 assertEquals(1, task.setExceptionCount());
677 try {
678 task.get();
679 shouldThrow();
680 } catch (ExecutionException success) {
681 assertSame(e, success.getCause());
682 tryToConfuseDoneTask(task);
683 checkCompletedAbnormally(task, success.getCause());
684 }
685 }
686
687 /**
688 * A runtime exception in task causes timed get to throw ExecutionException
689 */
690 public void testTimedGet_ExecutionException2() throws Exception {
691 final ArithmeticException e = new ArithmeticException();
692 final PublicFutureTask task = new PublicFutureTask(new Callable() {
693 public Object call() {
694 throw e;
695 }});
696
697 task.run();
698 try {
699 task.get(LONG_DELAY_MS, MILLISECONDS);
700 shouldThrow();
701 } catch (ExecutionException success) {
702 assertSame(e, success.getCause());
703 tryToConfuseDoneTask(task);
704 checkCompletedAbnormally(task, success.getCause());
705 }
706 }
707
708 /**
709 * get is interruptible
710 */
711 public void testGet_interruptible() {
712 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
713 final FutureTask task = new FutureTask(new NoOpCallable());
714 Thread t = newStartedThread(new CheckedRunnable() {
715 public void realRun() throws Exception {
716 Thread.currentThread().interrupt();
717 try {
718 task.get();
719 shouldThrow();
720 } catch (InterruptedException success) {}
721 assertFalse(Thread.interrupted());
722
723 pleaseInterrupt.countDown();
724 try {
725 task.get();
726 shouldThrow();
727 } catch (InterruptedException success) {}
728 assertFalse(Thread.interrupted());
729 }});
730
731 await(pleaseInterrupt);
732 t.interrupt();
733 awaitTermination(t);
734 checkNotDone(task);
735 }
736
737 /**
738 * timed get is interruptible
739 */
740 public void testTimedGet_interruptible() {
741 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
742 final FutureTask task = new FutureTask(new NoOpCallable());
743 Thread t = newStartedThread(new CheckedRunnable() {
744 public void realRun() throws Exception {
745 Thread.currentThread().interrupt();
746 try {
747 task.get(2*LONG_DELAY_MS, MILLISECONDS);
748 shouldThrow();
749 } catch (InterruptedException success) {}
750 assertFalse(Thread.interrupted());
751
752 pleaseInterrupt.countDown();
753 try {
754 task.get(2*LONG_DELAY_MS, MILLISECONDS);
755 shouldThrow();
756 } catch (InterruptedException success) {}
757 assertFalse(Thread.interrupted());
758 }});
759
760 await(pleaseInterrupt);
761 t.interrupt();
762 awaitTermination(t);
763 checkNotDone(task);
764 }
765
766 /**
767 * A timed out timed get throws TimeoutException
768 */
769 public void testGet_TimeoutException() throws Exception {
770 FutureTask task = new FutureTask(new NoOpCallable());
771 long startTime = System.nanoTime();
772 try {
773 task.get(timeoutMillis(), MILLISECONDS);
774 shouldThrow();
775 } catch (TimeoutException success) {
776 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
777 }
778 }
779
780 /**
781 * timed get with null TimeUnit throws NullPointerException
782 */
783 public void testGet_NullTimeUnit() throws Exception {
784 FutureTask task = new FutureTask(new NoOpCallable());
785 long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
786
787 for (long timeout : timeouts) {
788 try {
789 task.get(timeout, null);
790 shouldThrow();
791 } catch (NullPointerException success) {}
792 }
793
794 task.run();
795
796 for (long timeout : timeouts) {
797 try {
798 task.get(timeout, null);
799 shouldThrow();
800 } catch (NullPointerException success) {}
801 }
802 }
803
804 }