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