ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.58
Committed: Wed Jan 27 01:57:24 2021 UTC (3 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.57: +5 -6 lines
Log Message:
use diamond <> pervasively

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