ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.55
Committed: Thu Sep 5 21:37:25 2019 UTC (4 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.54: +2 -5 lines
Log Message:
testTimedGet_interruptible: rely on awaitTermination together with LONGER_DELAY_MS

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 {
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() {
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(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(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 =
633 new CheckedCallable<Object>() {
634 public Object realCall() throws InterruptedException {
635 pleaseCancel.countDown();
636 if (mayInterruptIfRunning) {
637 try {
638 delay(2*LONG_DELAY_MS);
639 } catch (InterruptedException success) {}
640 } else {
641 await(cancelled);
642 }
643 return two;
644 }};
645 final PublicFutureTask task = new PublicFutureTask(callable);
646
647 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
648 public void realRun() throws Exception {
649 pleaseCancel.countDown();
650 task.get();
651 }};
652 Thread t2 = new ThreadShouldThrow(CancellationException.class) {
653 public void realRun() throws Exception {
654 pleaseCancel.countDown();
655 task.get(2*LONG_DELAY_MS, MILLISECONDS);
656 }};
657 t1.start();
658 t2.start();
659 Thread t3 = newStartedThread(task);
660 await(pleaseCancel);
661 checkIsRunning(task);
662 task.cancel(mayInterruptIfRunning);
663 checkCancelled(task);
664 awaitTermination(t1);
665 awaitTermination(t2);
666 cancelled.countDown();
667 awaitTermination(t3);
668 assertEquals(1, task.runCount());
669 assertEquals(1, task.setCount());
670 assertEquals(0, task.setExceptionCount());
671 tryToConfuseDoneTask(task);
672 checkCancelled(task);
673 }
674
675 /**
676 * A runtime exception in task causes get to throw ExecutionException
677 */
678 public void testGet_ExecutionException() throws InterruptedException {
679 final ArithmeticException e = new ArithmeticException();
680 final PublicFutureTask task = new PublicFutureTask(new Callable() {
681 public Object call() {
682 throw e;
683 }});
684
685 task.run();
686 assertEquals(1, task.runCount());
687 assertEquals(0, task.setCount());
688 assertEquals(1, task.setExceptionCount());
689 try {
690 task.get();
691 shouldThrow();
692 } catch (ExecutionException success) {
693 assertSame(e, success.getCause());
694 tryToConfuseDoneTask(task);
695 checkCompletedAbnormally(task, success.getCause());
696 }
697 }
698
699 /**
700 * A runtime exception in task causes timed get to throw ExecutionException
701 */
702 public void testTimedGet_ExecutionException2() throws Exception {
703 final ArithmeticException e = new ArithmeticException();
704 final PublicFutureTask task = new PublicFutureTask(new Callable() {
705 public Object call() {
706 throw e;
707 }});
708
709 task.run();
710 try {
711 task.get(LONG_DELAY_MS, MILLISECONDS);
712 shouldThrow();
713 } catch (ExecutionException success) {
714 assertSame(e, success.getCause());
715 tryToConfuseDoneTask(task);
716 checkCompletedAbnormally(task, success.getCause());
717 }
718 }
719
720 /**
721 * get is interruptible
722 */
723 public void testGet_interruptible() {
724 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
725 final FutureTask task = new FutureTask(new NoOpCallable());
726 Thread t = newStartedThread(new CheckedRunnable() {
727 public void realRun() throws Exception {
728 Thread.currentThread().interrupt();
729 try {
730 task.get();
731 shouldThrow();
732 } catch (InterruptedException success) {}
733 assertFalse(Thread.interrupted());
734
735 pleaseInterrupt.countDown();
736 try {
737 task.get();
738 shouldThrow();
739 } catch (InterruptedException success) {}
740 assertFalse(Thread.interrupted());
741 }});
742
743 await(pleaseInterrupt);
744 t.interrupt();
745 awaitTermination(t);
746 checkNotDone(task);
747 }
748
749 /**
750 * timed get is interruptible
751 */
752 public void testTimedGet_interruptible() {
753 final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
754 final FutureTask task = new FutureTask(new NoOpCallable());
755 Thread t = newStartedThread(new CheckedRunnable() {
756 public void realRun() throws Exception {
757 Thread.currentThread().interrupt();
758 try {
759 task.get(randomTimeout(), randomTimeUnit());
760 shouldThrow();
761 } catch (InterruptedException success) {}
762 assertFalse(Thread.interrupted());
763
764 pleaseInterrupt.countDown();
765 try {
766 task.get(LONGER_DELAY_MS, MILLISECONDS);
767 shouldThrow();
768 } catch (InterruptedException success) {}
769 assertFalse(Thread.interrupted());
770 }});
771
772 await(pleaseInterrupt);
773 if (randomBoolean()) assertThreadBlocks(t, Thread.State.TIMED_WAITING);
774 t.interrupt();
775 awaitTermination(t);
776 checkNotDone(task);
777 }
778
779 /**
780 * A timed out timed get throws TimeoutException
781 */
782 public void testGet_TimeoutException() throws Exception {
783 FutureTask task = new FutureTask(new NoOpCallable());
784 long startTime = System.nanoTime();
785 try {
786 task.get(timeoutMillis(), MILLISECONDS);
787 shouldThrow();
788 } catch (TimeoutException success) {
789 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
790 }
791 }
792
793 /**
794 * timed get with null TimeUnit throws NullPointerException
795 */
796 public void testGet_NullTimeUnit() throws Exception {
797 FutureTask task = new FutureTask(new NoOpCallable());
798 long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
799
800 for (long timeout : timeouts) {
801 try {
802 task.get(timeout, null);
803 shouldThrow();
804 } catch (NullPointerException success) {}
805 }
806
807 task.run();
808
809 for (long timeout : timeouts) {
810 try {
811 task.get(timeout, null);
812 shouldThrow();
813 } catch (NullPointerException success) {}
814 }
815 }
816
817 /**
818 * timed get with most negative timeout works correctly (i.e. no
819 * underflow bug)
820 */
821 public void testGet_NegativeInfinityTimeout() throws Exception {
822 final ExecutorService pool = Executors.newFixedThreadPool(10);
823 final Runnable nop = new Runnable() { public void run() {}};
824 final FutureTask<Void> task = new FutureTask<>(nop, null);
825 final List<Future<?>> futures = new ArrayList<>();
826 Runnable r = new Runnable() { public void run() {
827 for (long timeout : new long[] { 0L, -1L, Long.MIN_VALUE }) {
828 try {
829 task.get(timeout, NANOSECONDS);
830 shouldThrow();
831 } catch (TimeoutException success) {
832 } catch (Throwable fail) {threadUnexpectedException(fail);}}}};
833 for (int i = 0; i < 10; i++)
834 futures.add(pool.submit(r));
835 try {
836 joinPool(pool);
837 for (Future<?> future : futures)
838 checkCompletedNormally(future, null);
839 } finally {
840 task.run(); // last resort to help terminate
841 }
842 }
843
844 /**
845 * toString indicates current completion state
846 */
847 public void testToString_incomplete() {
848 FutureTask<String> f = new FutureTask<>(() -> "");
849 assertTrue(f.toString().matches(".*\\[.*Not completed.*\\]"));
850 if (testImplementationDetails)
851 assertTrue(f.toString().startsWith(
852 identityString(f) + "[Not completed, task ="));
853 }
854
855 public void testToString_normal() {
856 FutureTask<String> f = new FutureTask<>(() -> "");
857 f.run();
858 assertTrue(f.toString().matches(".*\\[.*Completed normally.*\\]"));
859 if (testImplementationDetails)
860 assertEquals(identityString(f) + "[Completed normally]",
861 f.toString());
862 }
863
864 public void testToString_exception() {
865 FutureTask<String> f = new FutureTask<>(
866 () -> { throw new ArithmeticException(); });
867 f.run();
868 assertTrue(f.toString().matches(".*\\[.*Completed exceptionally.*\\]"));
869 if (testImplementationDetails)
870 assertTrue(f.toString().startsWith(
871 identityString(f) + "[Completed exceptionally: "));
872 }
873
874 public void testToString_cancelled() {
875 for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
876 FutureTask<String> f = new FutureTask<>(() -> "");
877 assertTrue(f.cancel(mayInterruptIfRunning));
878 assertTrue(f.toString().matches(".*\\[.*Cancelled.*\\]"));
879 if (testImplementationDetails)
880 assertEquals(identityString(f) + "[Cancelled]",
881 f.toString());
882 }
883 }
884
885 }