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