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