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 */ 6 7 package jsr166; 8 9 import static java.util.concurrent.TimeUnit.MILLISECONDS; 10 import static java.util.concurrent.TimeUnit.SECONDS; 11 12 import java.util.Arrays; 13 import java.util.Collections; 14 import java.util.HashSet; 15 import java.util.List; 16 import java.util.concurrent.CancellationException; 17 import java.util.concurrent.ExecutionException; 18 import java.util.concurrent.ForkJoinPool; 19 import java.util.concurrent.ForkJoinTask; 20 import java.util.concurrent.RecursiveAction; 21 import java.util.concurrent.TimeoutException; 22 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; 23 24 import junit.framework.Test; 25 import junit.framework.TestSuite; 26 27 public class ForkJoinTaskTest extends JSR166TestCase { 28 29 // android-note: Removed because the CTS runner does a bad job of 30 // retrying tests that have suite() declarations. 31 // 32 // public static void main(String[] args) { 33 // main(suite(), args); 34 // } 35 // public static Test suite() { 36 // return new TestSuite(ForkJoinTaskTest.class); 37 // } 38 39 // Runs with "mainPool" use > 1 thread. singletonPool tests use 1 40 static final int mainPoolSize = 41 Math.max(2, Runtime.getRuntime().availableProcessors()); 42 mainPool()43 private static ForkJoinPool mainPool() { 44 return new ForkJoinPool(mainPoolSize); 45 } 46 singletonPool()47 private static ForkJoinPool singletonPool() { 48 return new ForkJoinPool(1); 49 } 50 asyncSingletonPool()51 private static ForkJoinPool asyncSingletonPool() { 52 return new ForkJoinPool(1, 53 ForkJoinPool.defaultForkJoinWorkerThreadFactory, 54 null, true); 55 } 56 testInvokeOnPool(ForkJoinPool pool, RecursiveAction a)57 private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) { 58 try (PoolCleaner cleaner = cleaner(pool)) { 59 assertFalse(a.isDone()); 60 assertFalse(a.isCompletedNormally()); 61 assertFalse(a.isCompletedAbnormally()); 62 assertFalse(a.isCancelled()); 63 assertNull(a.getException()); 64 assertNull(a.getRawResult()); 65 66 assertNull(pool.invoke(a)); 67 68 assertTrue(a.isDone()); 69 assertTrue(a.isCompletedNormally()); 70 assertFalse(a.isCompletedAbnormally()); 71 assertFalse(a.isCancelled()); 72 assertNull(a.getException()); 73 assertNull(a.getRawResult()); 74 } 75 } 76 checkNotDone(ForkJoinTask a)77 void checkNotDone(ForkJoinTask a) { 78 assertFalse(a.isDone()); 79 assertFalse(a.isCompletedNormally()); 80 assertFalse(a.isCompletedAbnormally()); 81 assertFalse(a.isCancelled()); 82 assertNull(a.getException()); 83 assertNull(a.getRawResult()); 84 85 try { 86 a.get(0L, SECONDS); 87 shouldThrow(); 88 } catch (TimeoutException success) { 89 } catch (Throwable fail) { threadUnexpectedException(fail); } 90 } 91 checkCompletedNormally(ForkJoinTask<T> a)92 <T> void checkCompletedNormally(ForkJoinTask<T> a) { 93 checkCompletedNormally(a, null); 94 } 95 checkCompletedNormally(ForkJoinTask<T> a, T expected)96 <T> void checkCompletedNormally(ForkJoinTask<T> a, T expected) { 97 assertTrue(a.isDone()); 98 assertFalse(a.isCancelled()); 99 assertTrue(a.isCompletedNormally()); 100 assertFalse(a.isCompletedAbnormally()); 101 assertNull(a.getException()); 102 assertSame(expected, a.getRawResult()); 103 104 { 105 Thread.currentThread().interrupt(); 106 long startTime = System.nanoTime(); 107 assertSame(expected, a.join()); 108 assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); 109 Thread.interrupted(); 110 } 111 112 { 113 Thread.currentThread().interrupt(); 114 long startTime = System.nanoTime(); 115 a.quietlyJoin(); // should be no-op 116 assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); 117 Thread.interrupted(); 118 } 119 120 assertFalse(a.cancel(false)); 121 assertFalse(a.cancel(true)); 122 try { 123 assertSame(expected, a.get()); 124 } catch (Throwable fail) { threadUnexpectedException(fail); } 125 try { 126 assertSame(expected, a.get(5L, SECONDS)); 127 } catch (Throwable fail) { threadUnexpectedException(fail); } 128 } 129 130 void checkCancelled(ForkJoinTask a) { 131 assertTrue(a.isDone()); 132 assertTrue(a.isCancelled()); 133 assertFalse(a.isCompletedNormally()); 134 assertTrue(a.isCompletedAbnormally()); 135 assertTrue(a.getException() instanceof CancellationException); 136 assertNull(a.getRawResult()); 137 assertTrue(a.cancel(false)); 138 assertTrue(a.cancel(true)); 139 140 try { 141 Thread.currentThread().interrupt(); 142 a.join(); 143 shouldThrow(); 144 } catch (CancellationException success) { 145 } catch (Throwable fail) { threadUnexpectedException(fail); } 146 Thread.interrupted(); 147 148 { 149 long startTime = System.nanoTime(); 150 a.quietlyJoin(); // should be no-op 151 assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); 152 } 153 154 try { 155 a.get(); 156 shouldThrow(); 157 } catch (CancellationException success) { 158 } catch (Throwable fail) { threadUnexpectedException(fail); } 159 160 try { 161 a.get(5L, SECONDS); 162 shouldThrow(); 163 } catch (CancellationException success) { 164 } catch (Throwable fail) { threadUnexpectedException(fail); } 165 } 166 167 void checkCompletedAbnormally(ForkJoinTask a, Throwable t) { 168 assertTrue(a.isDone()); 169 assertFalse(a.isCancelled()); 170 assertFalse(a.isCompletedNormally()); 171 assertTrue(a.isCompletedAbnormally()); 172 assertSame(t.getClass(), a.getException().getClass()); 173 assertNull(a.getRawResult()); 174 assertFalse(a.cancel(false)); 175 assertFalse(a.cancel(true)); 176 177 try { 178 Thread.currentThread().interrupt(); 179 a.join(); 180 shouldThrow(); 181 } catch (Throwable expected) { 182 assertSame(t.getClass(), expected.getClass()); 183 } 184 Thread.interrupted(); 185 186 { 187 long startTime = System.nanoTime(); 188 a.quietlyJoin(); // should be no-op 189 assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS); 190 } 191 192 try { 193 a.get(); 194 shouldThrow(); 195 } catch (ExecutionException success) { 196 assertSame(t.getClass(), success.getCause().getClass()); 197 } catch (Throwable fail) { threadUnexpectedException(fail); } 198 199 try { 200 a.get(5L, SECONDS); 201 shouldThrow(); 202 } catch (ExecutionException success) { 203 assertSame(t.getClass(), success.getCause().getClass()); 204 } catch (Throwable fail) { threadUnexpectedException(fail); } 205 } 206 207 /* 208 * Testing coverage notes: 209 * 210 * To test extension methods and overrides, most tests use 211 * BinaryAsyncAction extension class that processes joins 212 * differently than supplied Recursive forms. 213 */ 214 215 public static final class FJException extends RuntimeException { 216 FJException() { super(); } 217 } 218 219 abstract static class BinaryAsyncAction extends ForkJoinTask<Void> { 220 private volatile int controlState; 221 222 static final AtomicIntegerFieldUpdater<BinaryAsyncAction> controlStateUpdater = 223 AtomicIntegerFieldUpdater.newUpdater(BinaryAsyncAction.class, 224 "controlState"); 225 226 private volatile BinaryAsyncAction parent; 227 228 private volatile BinaryAsyncAction sibling; 229 230 protected BinaryAsyncAction() { 231 } 232 233 public final Void getRawResult() { return null; } 234 protected final void setRawResult(Void mustBeNull) { } 235 236 public final void linkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) { 237 x.parent = y.parent = this; 238 x.sibling = y; 239 y.sibling = x; 240 } 241 242 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) { 243 } 244 245 protected boolean onException() { 246 return true; 247 } 248 249 public void linkAndForkSubtasks(BinaryAsyncAction x, BinaryAsyncAction y) { 250 linkSubtasks(x, y); 251 y.fork(); 252 x.fork(); 253 } 254 255 private void completeThis() { 256 super.complete(null); 257 } 258 259 private void completeThisExceptionally(Throwable ex) { 260 super.completeExceptionally(ex); 261 } 262 263 public boolean cancel(boolean mayInterruptIfRunning) { 264 if (super.cancel(mayInterruptIfRunning)) { 265 completeExceptionally(new FJException()); 266 return true; 267 } 268 return false; 269 } 270 271 public final void complete() { 272 BinaryAsyncAction a = this; 273 for (;;) { 274 BinaryAsyncAction s = a.sibling; 275 BinaryAsyncAction p = a.parent; 276 a.sibling = null; 277 a.parent = null; 278 a.completeThis(); 279 if (p == null || p.compareAndSetControlState(0, 1)) 280 break; 281 try { 282 p.onComplete(a, s); 283 } catch (Throwable rex) { 284 p.completeExceptionally(rex); 285 return; 286 } 287 a = p; 288 } 289 } 290 291 public final void completeExceptionally(Throwable ex) { 292 for (BinaryAsyncAction a = this;;) { 293 a.completeThisExceptionally(ex); 294 BinaryAsyncAction s = a.sibling; 295 if (s != null && !s.isDone()) 296 s.completeExceptionally(ex); 297 if ((a = a.parent) == null) 298 break; 299 } 300 } 301 302 public final BinaryAsyncAction getParent() { 303 return parent; 304 } 305 306 public BinaryAsyncAction getSibling() { 307 return sibling; 308 } 309 310 public void reinitialize() { 311 parent = sibling = null; 312 super.reinitialize(); 313 } 314 315 protected final int getControlState() { 316 return controlState; 317 } 318 319 protected final boolean compareAndSetControlState(int expect, 320 int update) { 321 return controlStateUpdater.compareAndSet(this, expect, update); 322 } 323 324 protected final void setControlState(int value) { 325 controlState = value; 326 } 327 328 protected final void incrementControlState() { 329 controlStateUpdater.incrementAndGet(this); 330 } 331 332 protected final void decrementControlState() { 333 controlStateUpdater.decrementAndGet(this); 334 } 335 336 } 337 338 static final class AsyncFib extends BinaryAsyncAction { 339 int number; 340 public AsyncFib(int n) { 341 this.number = n; 342 } 343 344 public final boolean exec() { 345 AsyncFib f = this; 346 int n = f.number; 347 while (n > 1) { 348 AsyncFib p = f; 349 AsyncFib r = new AsyncFib(n - 2); 350 f = new AsyncFib(--n); 351 p.linkSubtasks(r, f); 352 r.fork(); 353 } 354 f.complete(); 355 return false; 356 } 357 358 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) { 359 number = ((AsyncFib)x).number + ((AsyncFib)y).number; 360 } 361 } 362 363 static final class FailingAsyncFib extends BinaryAsyncAction { 364 int number; 365 public FailingAsyncFib(int n) { 366 this.number = n; 367 } 368 369 public final boolean exec() { 370 FailingAsyncFib f = this; 371 int n = f.number; 372 while (n > 1) { 373 FailingAsyncFib p = f; 374 FailingAsyncFib r = new FailingAsyncFib(n - 2); 375 f = new FailingAsyncFib(--n); 376 p.linkSubtasks(r, f); 377 r.fork(); 378 } 379 f.complete(); 380 return false; 381 } 382 383 protected void onComplete(BinaryAsyncAction x, BinaryAsyncAction y) { 384 completeExceptionally(new FJException()); 385 } 386 } 387 388 /** 389 * invoke returns when task completes normally. 390 * isCompletedAbnormally and isCancelled return false for normally 391 * completed tasks; getRawResult returns null. 392 */ 393 public void testInvoke() { 394 RecursiveAction a = new CheckedRecursiveAction() { 395 protected void realCompute() { 396 AsyncFib f = new AsyncFib(8); 397 assertNull(f.invoke()); 398 assertEquals(21, f.number); 399 checkCompletedNormally(f); 400 }}; 401 testInvokeOnPool(mainPool(), a); 402 } 403 404 /** 405 * quietlyInvoke task returns when task completes normally. 406 * isCompletedAbnormally and isCancelled return false for normally 407 * completed tasks 408 */ 409 public void testQuietlyInvoke() { 410 RecursiveAction a = new CheckedRecursiveAction() { 411 protected void realCompute() { 412 AsyncFib f = new AsyncFib(8); 413 f.quietlyInvoke(); 414 assertEquals(21, f.number); 415 checkCompletedNormally(f); 416 }}; 417 testInvokeOnPool(mainPool(), a); 418 } 419 420 /** 421 * join of a forked task returns when task completes 422 */ 423 public void testForkJoin() { 424 RecursiveAction a = new CheckedRecursiveAction() { 425 protected void realCompute() { 426 AsyncFib f = new AsyncFib(8); 427 assertSame(f, f.fork()); 428 assertNull(f.join()); 429 assertEquals(21, f.number); 430 checkCompletedNormally(f); 431 }}; 432 testInvokeOnPool(mainPool(), a); 433 } 434 435 /** 436 * get of a forked task returns when task completes 437 */ 438 public void testForkGet() { 439 RecursiveAction a = new CheckedRecursiveAction() { 440 protected void realCompute() throws Exception { 441 AsyncFib f = new AsyncFib(8); 442 assertSame(f, f.fork()); 443 assertNull(f.get()); 444 assertEquals(21, f.number); 445 checkCompletedNormally(f); 446 }}; 447 testInvokeOnPool(mainPool(), a); 448 } 449 450 /** 451 * timed get of a forked task returns when task completes 452 */ 453 public void testForkTimedGet() { 454 RecursiveAction a = new CheckedRecursiveAction() { 455 protected void realCompute() throws Exception { 456 AsyncFib f = new AsyncFib(8); 457 assertSame(f, f.fork()); 458 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS)); 459 assertEquals(21, f.number); 460 checkCompletedNormally(f); 461 }}; 462 testInvokeOnPool(mainPool(), a); 463 } 464 465 /** 466 * timed get with null time unit throws NPE 467 */ 468 public void testForkTimedGetNPE() { 469 RecursiveAction a = new CheckedRecursiveAction() { 470 protected void realCompute() throws Exception { 471 AsyncFib f = new AsyncFib(8); 472 assertSame(f, f.fork()); 473 try { 474 f.get(5L, null); 475 shouldThrow(); 476 } catch (NullPointerException success) {} 477 }}; 478 testInvokeOnPool(mainPool(), a); 479 } 480 481 /** 482 * quietlyJoin of a forked task returns when task completes 483 */ 484 public void testForkQuietlyJoin() { 485 RecursiveAction a = new CheckedRecursiveAction() { 486 protected void realCompute() { 487 AsyncFib f = new AsyncFib(8); 488 assertSame(f, f.fork()); 489 f.quietlyJoin(); 490 assertEquals(21, f.number); 491 checkCompletedNormally(f); 492 }}; 493 testInvokeOnPool(mainPool(), a); 494 } 495 496 /** 497 * helpQuiesce returns when tasks are complete. 498 * getQueuedTaskCount returns 0 when quiescent 499 */ 500 public void testForkHelpQuiesce() { 501 RecursiveAction a = new CheckedRecursiveAction() { 502 protected void realCompute() { 503 AsyncFib f = new AsyncFib(8); 504 assertSame(f, f.fork()); 505 helpQuiesce(); 506 assertEquals(21, f.number); 507 assertEquals(0, getQueuedTaskCount()); 508 checkCompletedNormally(f); 509 }}; 510 testInvokeOnPool(mainPool(), a); 511 } 512 513 /** 514 * invoke task throws exception when task completes abnormally 515 */ 516 public void testAbnormalInvoke() { 517 RecursiveAction a = new CheckedRecursiveAction() { 518 protected void realCompute() { 519 FailingAsyncFib f = new FailingAsyncFib(8); 520 try { 521 f.invoke(); 522 shouldThrow(); 523 } catch (FJException success) { 524 checkCompletedAbnormally(f, success); 525 } 526 }}; 527 testInvokeOnPool(mainPool(), a); 528 } 529 530 /** 531 * quietlyInvoke task returns when task completes abnormally 532 */ 533 public void testAbnormalQuietlyInvoke() { 534 RecursiveAction a = new CheckedRecursiveAction() { 535 protected void realCompute() { 536 FailingAsyncFib f = new FailingAsyncFib(8); 537 f.quietlyInvoke(); 538 assertTrue(f.getException() instanceof FJException); 539 checkCompletedAbnormally(f, f.getException()); 540 }}; 541 testInvokeOnPool(mainPool(), a); 542 } 543 544 /** 545 * join of a forked task throws exception when task completes abnormally 546 */ 547 public void testAbnormalForkJoin() { 548 RecursiveAction a = new CheckedRecursiveAction() { 549 protected void realCompute() { 550 FailingAsyncFib f = new FailingAsyncFib(8); 551 assertSame(f, f.fork()); 552 try { 553 f.join(); 554 shouldThrow(); 555 } catch (FJException success) { 556 checkCompletedAbnormally(f, success); 557 } 558 }}; 559 testInvokeOnPool(mainPool(), a); 560 } 561 562 /** 563 * get of a forked task throws exception when task completes abnormally 564 */ 565 public void testAbnormalForkGet() { 566 RecursiveAction a = new CheckedRecursiveAction() { 567 protected void realCompute() throws Exception { 568 FailingAsyncFib f = new FailingAsyncFib(8); 569 assertSame(f, f.fork()); 570 try { 571 f.get(); 572 shouldThrow(); 573 } catch (ExecutionException success) { 574 Throwable cause = success.getCause(); 575 assertTrue(cause instanceof FJException); 576 checkCompletedAbnormally(f, cause); 577 } 578 }}; 579 testInvokeOnPool(mainPool(), a); 580 } 581 582 /** 583 * timed get of a forked task throws exception when task completes abnormally 584 */ 585 public void testAbnormalForkTimedGet() { 586 RecursiveAction a = new CheckedRecursiveAction() { 587 protected void realCompute() throws Exception { 588 FailingAsyncFib f = new FailingAsyncFib(8); 589 assertSame(f, f.fork()); 590 try { 591 f.get(LONG_DELAY_MS, MILLISECONDS); 592 shouldThrow(); 593 } catch (ExecutionException success) { 594 Throwable cause = success.getCause(); 595 assertTrue(cause instanceof FJException); 596 checkCompletedAbnormally(f, cause); 597 } 598 }}; 599 testInvokeOnPool(mainPool(), a); 600 } 601 602 /** 603 * quietlyJoin of a forked task returns when task completes abnormally 604 */ 605 public void testAbnormalForkQuietlyJoin() { 606 RecursiveAction a = new CheckedRecursiveAction() { 607 protected void realCompute() { 608 FailingAsyncFib f = new FailingAsyncFib(8); 609 assertSame(f, f.fork()); 610 f.quietlyJoin(); 611 assertTrue(f.getException() instanceof FJException); 612 checkCompletedAbnormally(f, f.getException()); 613 }}; 614 testInvokeOnPool(mainPool(), a); 615 } 616 617 /** 618 * invoke task throws exception when task cancelled 619 */ 620 public void testCancelledInvoke() { 621 RecursiveAction a = new CheckedRecursiveAction() { 622 protected void realCompute() { 623 AsyncFib f = new AsyncFib(8); 624 assertTrue(f.cancel(true)); 625 try { 626 f.invoke(); 627 shouldThrow(); 628 } catch (CancellationException success) { 629 checkCancelled(f); 630 } 631 }}; 632 testInvokeOnPool(mainPool(), a); 633 } 634 635 /** 636 * join of a forked task throws exception when task cancelled 637 */ 638 public void testCancelledForkJoin() { 639 RecursiveAction a = new CheckedRecursiveAction() { 640 protected void realCompute() { 641 AsyncFib f = new AsyncFib(8); 642 assertTrue(f.cancel(true)); 643 assertSame(f, f.fork()); 644 try { 645 f.join(); 646 shouldThrow(); 647 } catch (CancellationException success) { 648 checkCancelled(f); 649 } 650 }}; 651 testInvokeOnPool(mainPool(), a); 652 } 653 654 /** 655 * get of a forked task throws exception when task cancelled 656 */ 657 public void testCancelledForkGet() { 658 RecursiveAction a = new CheckedRecursiveAction() { 659 protected void realCompute() throws Exception { 660 AsyncFib f = new AsyncFib(8); 661 assertTrue(f.cancel(true)); 662 assertSame(f, f.fork()); 663 try { 664 f.get(); 665 shouldThrow(); 666 } catch (CancellationException success) { 667 checkCancelled(f); 668 } 669 }}; 670 testInvokeOnPool(mainPool(), a); 671 } 672 673 /** 674 * timed get of a forked task throws exception when task cancelled 675 */ 676 public void testCancelledForkTimedGet() throws Exception { 677 RecursiveAction a = new CheckedRecursiveAction() { 678 protected void realCompute() throws Exception { 679 AsyncFib f = new AsyncFib(8); 680 assertTrue(f.cancel(true)); 681 assertSame(f, f.fork()); 682 try { 683 f.get(LONG_DELAY_MS, MILLISECONDS); 684 shouldThrow(); 685 } catch (CancellationException success) { 686 checkCancelled(f); 687 } 688 }}; 689 testInvokeOnPool(mainPool(), a); 690 } 691 692 /** 693 * quietlyJoin of a forked task returns when task cancelled 694 */ 695 public void testCancelledForkQuietlyJoin() { 696 RecursiveAction a = new CheckedRecursiveAction() { 697 protected void realCompute() { 698 AsyncFib f = new AsyncFib(8); 699 assertTrue(f.cancel(true)); 700 assertSame(f, f.fork()); 701 f.quietlyJoin(); 702 checkCancelled(f); 703 }}; 704 testInvokeOnPool(mainPool(), a); 705 } 706 707 /** 708 * getPool of executing task returns its pool 709 */ 710 public void testGetPool() { 711 final ForkJoinPool mainPool = mainPool(); 712 RecursiveAction a = new CheckedRecursiveAction() { 713 protected void realCompute() { 714 assertSame(mainPool, getPool()); 715 }}; 716 testInvokeOnPool(mainPool, a); 717 } 718 719 /** 720 * getPool of non-FJ task returns null 721 */ 722 public void testGetPool2() { 723 RecursiveAction a = new CheckedRecursiveAction() { 724 protected void realCompute() { 725 assertNull(getPool()); 726 }}; 727 assertNull(a.invoke()); 728 } 729 730 /** 731 * inForkJoinPool of executing task returns true 732 */ 733 public void testInForkJoinPool() { 734 RecursiveAction a = new CheckedRecursiveAction() { 735 protected void realCompute() { 736 assertTrue(inForkJoinPool()); 737 }}; 738 testInvokeOnPool(mainPool(), a); 739 } 740 741 /** 742 * inForkJoinPool of non-FJ task returns false 743 */ 744 public void testInForkJoinPool2() { 745 RecursiveAction a = new CheckedRecursiveAction() { 746 protected void realCompute() { 747 assertFalse(inForkJoinPool()); 748 }}; 749 assertNull(a.invoke()); 750 } 751 752 /** 753 * setRawResult(null) succeeds 754 */ 755 public void testSetRawResult() { 756 RecursiveAction a = new CheckedRecursiveAction() { 757 protected void realCompute() { 758 setRawResult(null); 759 assertNull(getRawResult()); 760 }}; 761 assertNull(a.invoke()); 762 } 763 764 /** 765 * invoke task throws exception after invoking completeExceptionally 766 */ 767 public void testCompleteExceptionally() { 768 RecursiveAction a = new CheckedRecursiveAction() { 769 protected void realCompute() { 770 AsyncFib f = new AsyncFib(8); 771 f.completeExceptionally(new FJException()); 772 try { 773 f.invoke(); 774 shouldThrow(); 775 } catch (FJException success) { 776 checkCompletedAbnormally(f, success); 777 } 778 }}; 779 testInvokeOnPool(mainPool(), a); 780 } 781 782 /** 783 * completeExceptionally(null) surprisingly has the same effect as 784 * completeExceptionally(new RuntimeException()) 785 */ 786 public void testCompleteExceptionally_null() { 787 RecursiveAction a = new CheckedRecursiveAction() { 788 protected void realCompute() { 789 AsyncFib f = new AsyncFib(8); 790 f.completeExceptionally(null); 791 try { 792 f.invoke(); 793 shouldThrow(); 794 } catch (RuntimeException success) { 795 assertSame(success.getClass(), RuntimeException.class); 796 assertNull(success.getCause()); 797 checkCompletedAbnormally(f, success); 798 } 799 }}; 800 testInvokeOnPool(mainPool(), a); 801 } 802 803 /** 804 * invokeAll(t1, t2) invokes all task arguments 805 */ 806 public void testInvokeAll2() { 807 RecursiveAction a = new CheckedRecursiveAction() { 808 protected void realCompute() { 809 AsyncFib f = new AsyncFib(8); 810 AsyncFib g = new AsyncFib(9); 811 invokeAll(f, g); 812 assertEquals(21, f.number); 813 assertEquals(34, g.number); 814 checkCompletedNormally(f); 815 checkCompletedNormally(g); 816 }}; 817 testInvokeOnPool(mainPool(), a); 818 } 819 820 /** 821 * invokeAll(tasks) with 1 argument invokes task 822 */ 823 public void testInvokeAll1() { 824 RecursiveAction a = new CheckedRecursiveAction() { 825 protected void realCompute() { 826 AsyncFib f = new AsyncFib(8); 827 invokeAll(f); 828 checkCompletedNormally(f); 829 assertEquals(21, f.number); 830 }}; 831 testInvokeOnPool(mainPool(), a); 832 } 833 834 /** 835 * invokeAll(tasks) with > 2 argument invokes tasks 836 */ 837 public void testInvokeAll3() { 838 RecursiveAction a = new CheckedRecursiveAction() { 839 protected void realCompute() { 840 AsyncFib f = new AsyncFib(8); 841 AsyncFib g = new AsyncFib(9); 842 AsyncFib h = new AsyncFib(7); 843 invokeAll(f, g, h); 844 assertEquals(21, f.number); 845 assertEquals(34, g.number); 846 assertEquals(13, h.number); 847 checkCompletedNormally(f); 848 checkCompletedNormally(g); 849 checkCompletedNormally(h); 850 }}; 851 testInvokeOnPool(mainPool(), a); 852 } 853 854 /** 855 * invokeAll(collection) invokes all tasks in the collection 856 */ 857 public void testInvokeAllCollection() { 858 RecursiveAction a = new CheckedRecursiveAction() { 859 protected void realCompute() { 860 AsyncFib f = new AsyncFib(8); 861 AsyncFib g = new AsyncFib(9); 862 AsyncFib h = new AsyncFib(7); 863 HashSet set = new HashSet(); 864 set.add(f); 865 set.add(g); 866 set.add(h); 867 invokeAll(set); 868 assertEquals(21, f.number); 869 assertEquals(34, g.number); 870 assertEquals(13, h.number); 871 checkCompletedNormally(f); 872 checkCompletedNormally(g); 873 checkCompletedNormally(h); 874 }}; 875 testInvokeOnPool(mainPool(), a); 876 } 877 878 /** 879 * invokeAll(tasks) with any null task throws NPE 880 */ 881 public void testInvokeAllNPE() { 882 RecursiveAction a = new CheckedRecursiveAction() { 883 protected void realCompute() { 884 AsyncFib f = new AsyncFib(8); 885 AsyncFib g = new AsyncFib(9); 886 AsyncFib h = null; 887 try { 888 invokeAll(f, g, h); 889 shouldThrow(); 890 } catch (NullPointerException success) {} 891 }}; 892 testInvokeOnPool(mainPool(), a); 893 } 894 895 /** 896 * invokeAll(t1, t2) throw exception if any task does 897 */ 898 public void testAbnormalInvokeAll2() { 899 RecursiveAction a = new CheckedRecursiveAction() { 900 protected void realCompute() { 901 AsyncFib f = new AsyncFib(8); 902 FailingAsyncFib g = new FailingAsyncFib(9); 903 ForkJoinTask[] tasks = { f, g }; 904 Collections.shuffle(Arrays.asList(tasks)); 905 try { 906 invokeAll(tasks); 907 shouldThrow(); 908 } catch (FJException success) { 909 checkCompletedAbnormally(g, success); 910 } 911 }}; 912 testInvokeOnPool(mainPool(), a); 913 } 914 915 /** 916 * invokeAll(tasks) with 1 argument throws exception if task does 917 */ 918 public void testAbnormalInvokeAll1() { 919 RecursiveAction a = new CheckedRecursiveAction() { 920 protected void realCompute() { 921 FailingAsyncFib g = new FailingAsyncFib(9); 922 try { 923 invokeAll(g); 924 shouldThrow(); 925 } catch (FJException success) { 926 checkCompletedAbnormally(g, success); 927 } 928 }}; 929 testInvokeOnPool(mainPool(), a); 930 } 931 932 /** 933 * invokeAll(tasks) with > 2 argument throws exception if any task does 934 */ 935 public void testAbnormalInvokeAll3() { 936 RecursiveAction a = new CheckedRecursiveAction() { 937 protected void realCompute() { 938 AsyncFib f = new AsyncFib(8); 939 FailingAsyncFib g = new FailingAsyncFib(9); 940 AsyncFib h = new AsyncFib(7); 941 ForkJoinTask[] tasks = { f, g, h }; 942 Collections.shuffle(Arrays.asList(tasks)); 943 try { 944 invokeAll(tasks); 945 shouldThrow(); 946 } catch (FJException success) { 947 checkCompletedAbnormally(g, success); 948 } 949 }}; 950 testInvokeOnPool(mainPool(), a); 951 } 952 953 /** 954 * invokeAll(collection) throws exception if any task does 955 */ 956 public void testAbnormalInvokeAllCollection() { 957 RecursiveAction a = new CheckedRecursiveAction() { 958 protected void realCompute() { 959 FailingAsyncFib f = new FailingAsyncFib(8); 960 AsyncFib g = new AsyncFib(9); 961 AsyncFib h = new AsyncFib(7); 962 ForkJoinTask[] tasks = { f, g, h }; 963 List taskList = Arrays.asList(tasks); 964 Collections.shuffle(taskList); 965 try { 966 invokeAll(taskList); 967 shouldThrow(); 968 } catch (FJException success) { 969 checkCompletedAbnormally(f, success); 970 } 971 }}; 972 testInvokeOnPool(mainPool(), a); 973 } 974 975 /** 976 * tryUnfork returns true for most recent unexecuted task, 977 * and suppresses execution 978 */ 979 public void testTryUnfork() { 980 RecursiveAction a = new CheckedRecursiveAction() { 981 protected void realCompute() { 982 AsyncFib g = new AsyncFib(9); 983 assertSame(g, g.fork()); 984 AsyncFib f = new AsyncFib(8); 985 assertSame(f, f.fork()); 986 assertTrue(f.tryUnfork()); 987 helpQuiesce(); 988 checkNotDone(f); 989 checkCompletedNormally(g); 990 }}; 991 testInvokeOnPool(singletonPool(), a); 992 } 993 994 /** 995 * getSurplusQueuedTaskCount returns > 0 when 996 * there are more tasks than threads 997 */ 998 public void testGetSurplusQueuedTaskCount() { 999 RecursiveAction a = new CheckedRecursiveAction() { 1000 protected void realCompute() { 1001 AsyncFib h = new AsyncFib(7); 1002 assertSame(h, h.fork()); 1003 AsyncFib g = new AsyncFib(9); 1004 assertSame(g, g.fork()); 1005 AsyncFib f = new AsyncFib(8); 1006 assertSame(f, f.fork()); 1007 assertTrue(getSurplusQueuedTaskCount() > 0); 1008 helpQuiesce(); 1009 assertEquals(0, getSurplusQueuedTaskCount()); 1010 checkCompletedNormally(f); 1011 checkCompletedNormally(g); 1012 checkCompletedNormally(h); 1013 }}; 1014 testInvokeOnPool(singletonPool(), a); 1015 } 1016 1017 /** 1018 * peekNextLocalTask returns most recent unexecuted task. 1019 */ 1020 public void testPeekNextLocalTask() { 1021 RecursiveAction a = new CheckedRecursiveAction() { 1022 protected void realCompute() { 1023 AsyncFib g = new AsyncFib(9); 1024 assertSame(g, g.fork()); 1025 AsyncFib f = new AsyncFib(8); 1026 assertSame(f, f.fork()); 1027 assertSame(f, peekNextLocalTask()); 1028 assertNull(f.join()); 1029 checkCompletedNormally(f); 1030 helpQuiesce(); 1031 checkCompletedNormally(g); 1032 }}; 1033 testInvokeOnPool(singletonPool(), a); 1034 } 1035 1036 /** 1037 * pollNextLocalTask returns most recent unexecuted task without 1038 * executing it 1039 */ 1040 public void testPollNextLocalTask() { 1041 RecursiveAction a = new CheckedRecursiveAction() { 1042 protected void realCompute() { 1043 AsyncFib g = new AsyncFib(9); 1044 assertSame(g, g.fork()); 1045 AsyncFib f = new AsyncFib(8); 1046 assertSame(f, f.fork()); 1047 assertSame(f, pollNextLocalTask()); 1048 helpQuiesce(); 1049 checkNotDone(f); 1050 assertEquals(34, g.number); 1051 checkCompletedNormally(g); 1052 }}; 1053 testInvokeOnPool(singletonPool(), a); 1054 } 1055 1056 /** 1057 * pollTask returns an unexecuted task without executing it 1058 */ 1059 public void testPollTask() { 1060 RecursiveAction a = new CheckedRecursiveAction() { 1061 protected void realCompute() { 1062 AsyncFib g = new AsyncFib(9); 1063 assertSame(g, g.fork()); 1064 AsyncFib f = new AsyncFib(8); 1065 assertSame(f, f.fork()); 1066 assertSame(f, pollTask()); 1067 helpQuiesce(); 1068 checkNotDone(f); 1069 checkCompletedNormally(g); 1070 }}; 1071 testInvokeOnPool(singletonPool(), a); 1072 } 1073 1074 /** 1075 * peekNextLocalTask returns least recent unexecuted task in async mode 1076 */ 1077 public void testPeekNextLocalTaskAsync() { 1078 RecursiveAction a = new CheckedRecursiveAction() { 1079 protected void realCompute() { 1080 AsyncFib g = new AsyncFib(9); 1081 assertSame(g, g.fork()); 1082 AsyncFib f = new AsyncFib(8); 1083 assertSame(f, f.fork()); 1084 assertSame(g, peekNextLocalTask()); 1085 assertNull(f.join()); 1086 helpQuiesce(); 1087 checkCompletedNormally(f); 1088 assertEquals(34, g.number); 1089 checkCompletedNormally(g); 1090 }}; 1091 testInvokeOnPool(asyncSingletonPool(), a); 1092 } 1093 1094 /** 1095 * pollNextLocalTask returns least recent unexecuted task without 1096 * executing it, in async mode 1097 */ 1098 public void testPollNextLocalTaskAsync() { 1099 RecursiveAction a = new CheckedRecursiveAction() { 1100 protected void realCompute() { 1101 AsyncFib g = new AsyncFib(9); 1102 assertSame(g, g.fork()); 1103 AsyncFib f = new AsyncFib(8); 1104 assertSame(f, f.fork()); 1105 assertSame(g, pollNextLocalTask()); 1106 helpQuiesce(); 1107 assertEquals(21, f.number); 1108 checkCompletedNormally(f); 1109 checkNotDone(g); 1110 }}; 1111 testInvokeOnPool(asyncSingletonPool(), a); 1112 } 1113 1114 /** 1115 * pollTask returns an unexecuted task without executing it, in 1116 * async mode 1117 */ 1118 public void testPollTaskAsync() { 1119 RecursiveAction a = new CheckedRecursiveAction() { 1120 protected void realCompute() { 1121 AsyncFib g = new AsyncFib(9); 1122 assertSame(g, g.fork()); 1123 AsyncFib f = new AsyncFib(8); 1124 assertSame(f, f.fork()); 1125 assertSame(g, pollTask()); 1126 helpQuiesce(); 1127 assertEquals(21, f.number); 1128 checkCompletedNormally(f); 1129 checkNotDone(g); 1130 }}; 1131 testInvokeOnPool(asyncSingletonPool(), a); 1132 } 1133 1134 // versions for singleton pools 1135 1136 /** 1137 * invoke returns when task completes normally. 1138 * isCompletedAbnormally and isCancelled return false for normally 1139 * completed tasks; getRawResult returns null. 1140 */ 1141 public void testInvokeSingleton() { 1142 RecursiveAction a = new CheckedRecursiveAction() { 1143 protected void realCompute() { 1144 AsyncFib f = new AsyncFib(8); 1145 assertNull(f.invoke()); 1146 assertEquals(21, f.number); 1147 checkCompletedNormally(f); 1148 }}; 1149 testInvokeOnPool(singletonPool(), a); 1150 } 1151 1152 /** 1153 * quietlyInvoke task returns when task completes normally. 1154 * isCompletedAbnormally and isCancelled return false for normally 1155 * completed tasks 1156 */ 1157 public void testQuietlyInvokeSingleton() { 1158 RecursiveAction a = new CheckedRecursiveAction() { 1159 protected void realCompute() { 1160 AsyncFib f = new AsyncFib(8); 1161 f.quietlyInvoke(); 1162 assertEquals(21, f.number); 1163 checkCompletedNormally(f); 1164 }}; 1165 testInvokeOnPool(singletonPool(), a); 1166 } 1167 1168 /** 1169 * join of a forked task returns when task completes 1170 */ 1171 public void testForkJoinSingleton() { 1172 RecursiveAction a = new CheckedRecursiveAction() { 1173 protected void realCompute() { 1174 AsyncFib f = new AsyncFib(8); 1175 assertSame(f, f.fork()); 1176 assertNull(f.join()); 1177 assertEquals(21, f.number); 1178 checkCompletedNormally(f); 1179 }}; 1180 testInvokeOnPool(singletonPool(), a); 1181 } 1182 1183 /** 1184 * get of a forked task returns when task completes 1185 */ 1186 public void testForkGetSingleton() { 1187 RecursiveAction a = new CheckedRecursiveAction() { 1188 protected void realCompute() throws Exception { 1189 AsyncFib f = new AsyncFib(8); 1190 assertSame(f, f.fork()); 1191 assertNull(f.get()); 1192 assertEquals(21, f.number); 1193 checkCompletedNormally(f); 1194 }}; 1195 testInvokeOnPool(singletonPool(), a); 1196 } 1197 1198 /** 1199 * timed get of a forked task returns when task completes 1200 */ 1201 public void testForkTimedGetSingleton() { 1202 RecursiveAction a = new CheckedRecursiveAction() { 1203 protected void realCompute() throws Exception { 1204 AsyncFib f = new AsyncFib(8); 1205 assertSame(f, f.fork()); 1206 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS)); 1207 assertEquals(21, f.number); 1208 checkCompletedNormally(f); 1209 }}; 1210 testInvokeOnPool(singletonPool(), a); 1211 } 1212 1213 /** 1214 * timed get with null time unit throws NPE 1215 */ 1216 public void testForkTimedGetNPESingleton() { 1217 RecursiveAction a = new CheckedRecursiveAction() { 1218 protected void realCompute() throws Exception { 1219 AsyncFib f = new AsyncFib(8); 1220 assertSame(f, f.fork()); 1221 try { 1222 f.get(5L, null); 1223 shouldThrow(); 1224 } catch (NullPointerException success) {} 1225 }}; 1226 testInvokeOnPool(singletonPool(), a); 1227 } 1228 1229 /** 1230 * quietlyJoin of a forked task returns when task completes 1231 */ 1232 public void testForkQuietlyJoinSingleton() { 1233 RecursiveAction a = new CheckedRecursiveAction() { 1234 protected void realCompute() { 1235 AsyncFib f = new AsyncFib(8); 1236 assertSame(f, f.fork()); 1237 f.quietlyJoin(); 1238 assertEquals(21, f.number); 1239 checkCompletedNormally(f); 1240 }}; 1241 testInvokeOnPool(singletonPool(), a); 1242 } 1243 1244 /** 1245 * helpQuiesce returns when tasks are complete. 1246 * getQueuedTaskCount returns 0 when quiescent 1247 */ 1248 public void testForkHelpQuiesceSingleton() { 1249 RecursiveAction a = new CheckedRecursiveAction() { 1250 protected void realCompute() { 1251 AsyncFib f = new AsyncFib(8); 1252 assertSame(f, f.fork()); 1253 helpQuiesce(); 1254 assertEquals(0, getQueuedTaskCount()); 1255 assertEquals(21, f.number); 1256 checkCompletedNormally(f); 1257 }}; 1258 testInvokeOnPool(singletonPool(), a); 1259 } 1260 1261 /** 1262 * invoke task throws exception when task completes abnormally 1263 */ 1264 public void testAbnormalInvokeSingleton() { 1265 RecursiveAction a = new CheckedRecursiveAction() { 1266 protected void realCompute() { 1267 FailingAsyncFib f = new FailingAsyncFib(8); 1268 try { 1269 f.invoke(); 1270 shouldThrow(); 1271 } catch (FJException success) { 1272 checkCompletedAbnormally(f, success); 1273 } 1274 }}; 1275 testInvokeOnPool(singletonPool(), a); 1276 } 1277 1278 /** 1279 * quietlyInvoke task returns when task completes abnormally 1280 */ 1281 public void testAbnormalQuietlyInvokeSingleton() { 1282 RecursiveAction a = new CheckedRecursiveAction() { 1283 protected void realCompute() { 1284 FailingAsyncFib f = new FailingAsyncFib(8); 1285 f.quietlyInvoke(); 1286 assertTrue(f.getException() instanceof FJException); 1287 checkCompletedAbnormally(f, f.getException()); 1288 }}; 1289 testInvokeOnPool(singletonPool(), a); 1290 } 1291 1292 /** 1293 * join of a forked task throws exception when task completes abnormally 1294 */ 1295 public void testAbnormalForkJoinSingleton() { 1296 RecursiveAction a = new CheckedRecursiveAction() { 1297 protected void realCompute() { 1298 FailingAsyncFib f = new FailingAsyncFib(8); 1299 assertSame(f, f.fork()); 1300 try { 1301 f.join(); 1302 shouldThrow(); 1303 } catch (FJException success) { 1304 checkCompletedAbnormally(f, success); 1305 } 1306 }}; 1307 testInvokeOnPool(singletonPool(), a); 1308 } 1309 1310 /** 1311 * get of a forked task throws exception when task completes abnormally 1312 */ 1313 public void testAbnormalForkGetSingleton() { 1314 RecursiveAction a = new CheckedRecursiveAction() { 1315 protected void realCompute() throws Exception { 1316 FailingAsyncFib f = new FailingAsyncFib(8); 1317 assertSame(f, f.fork()); 1318 try { 1319 f.get(); 1320 shouldThrow(); 1321 } catch (ExecutionException success) { 1322 Throwable cause = success.getCause(); 1323 assertTrue(cause instanceof FJException); 1324 checkCompletedAbnormally(f, cause); 1325 } 1326 }}; 1327 testInvokeOnPool(singletonPool(), a); 1328 } 1329 1330 /** 1331 * timed get of a forked task throws exception when task completes abnormally 1332 */ 1333 public void testAbnormalForkTimedGetSingleton() { 1334 RecursiveAction a = new CheckedRecursiveAction() { 1335 protected void realCompute() throws Exception { 1336 FailingAsyncFib f = new FailingAsyncFib(8); 1337 assertSame(f, f.fork()); 1338 try { 1339 f.get(LONG_DELAY_MS, MILLISECONDS); 1340 shouldThrow(); 1341 } catch (ExecutionException success) { 1342 Throwable cause = success.getCause(); 1343 assertTrue(cause instanceof FJException); 1344 checkCompletedAbnormally(f, cause); 1345 } 1346 }}; 1347 testInvokeOnPool(singletonPool(), a); 1348 } 1349 1350 /** 1351 * quietlyJoin of a forked task returns when task completes abnormally 1352 */ 1353 public void testAbnormalForkQuietlyJoinSingleton() { 1354 RecursiveAction a = new CheckedRecursiveAction() { 1355 protected void realCompute() { 1356 FailingAsyncFib f = new FailingAsyncFib(8); 1357 assertSame(f, f.fork()); 1358 f.quietlyJoin(); 1359 assertTrue(f.getException() instanceof FJException); 1360 checkCompletedAbnormally(f, f.getException()); 1361 }}; 1362 testInvokeOnPool(singletonPool(), a); 1363 } 1364 1365 /** 1366 * invoke task throws exception when task cancelled 1367 */ 1368 public void testCancelledInvokeSingleton() { 1369 RecursiveAction a = new CheckedRecursiveAction() { 1370 protected void realCompute() { 1371 AsyncFib f = new AsyncFib(8); 1372 assertTrue(f.cancel(true)); 1373 try { 1374 f.invoke(); 1375 shouldThrow(); 1376 } catch (CancellationException success) { 1377 checkCancelled(f); 1378 } 1379 }}; 1380 testInvokeOnPool(singletonPool(), a); 1381 } 1382 1383 /** 1384 * join of a forked task throws exception when task cancelled 1385 */ 1386 public void testCancelledForkJoinSingleton() { 1387 RecursiveAction a = new CheckedRecursiveAction() { 1388 protected void realCompute() { 1389 AsyncFib f = new AsyncFib(8); 1390 assertTrue(f.cancel(true)); 1391 assertSame(f, f.fork()); 1392 try { 1393 f.join(); 1394 shouldThrow(); 1395 } catch (CancellationException success) { 1396 checkCancelled(f); 1397 } 1398 }}; 1399 testInvokeOnPool(singletonPool(), a); 1400 } 1401 1402 /** 1403 * get of a forked task throws exception when task cancelled 1404 */ 1405 public void testCancelledForkGetSingleton() { 1406 RecursiveAction a = new CheckedRecursiveAction() { 1407 protected void realCompute() throws Exception { 1408 AsyncFib f = new AsyncFib(8); 1409 assertTrue(f.cancel(true)); 1410 assertSame(f, f.fork()); 1411 try { 1412 f.get(); 1413 shouldThrow(); 1414 } catch (CancellationException success) { 1415 checkCancelled(f); 1416 } 1417 }}; 1418 testInvokeOnPool(singletonPool(), a); 1419 } 1420 1421 /** 1422 * timed get of a forked task throws exception when task cancelled 1423 */ 1424 public void testCancelledForkTimedGetSingleton() throws Exception { 1425 RecursiveAction a = new CheckedRecursiveAction() { 1426 protected void realCompute() throws Exception { 1427 AsyncFib f = new AsyncFib(8); 1428 assertTrue(f.cancel(true)); 1429 assertSame(f, f.fork()); 1430 try { 1431 f.get(LONG_DELAY_MS, MILLISECONDS); 1432 shouldThrow(); 1433 } catch (CancellationException success) { 1434 checkCancelled(f); 1435 } 1436 }}; 1437 testInvokeOnPool(singletonPool(), a); 1438 } 1439 1440 /** 1441 * quietlyJoin of a forked task returns when task cancelled 1442 */ 1443 public void testCancelledForkQuietlyJoinSingleton() { 1444 RecursiveAction a = new CheckedRecursiveAction() { 1445 protected void realCompute() { 1446 AsyncFib f = new AsyncFib(8); 1447 assertTrue(f.cancel(true)); 1448 assertSame(f, f.fork()); 1449 f.quietlyJoin(); 1450 checkCancelled(f); 1451 }}; 1452 testInvokeOnPool(singletonPool(), a); 1453 } 1454 1455 /** 1456 * invoke task throws exception after invoking completeExceptionally 1457 */ 1458 public void testCompleteExceptionallySingleton() { 1459 RecursiveAction a = new CheckedRecursiveAction() { 1460 protected void realCompute() { 1461 AsyncFib f = new AsyncFib(8); 1462 f.completeExceptionally(new FJException()); 1463 try { 1464 f.invoke(); 1465 shouldThrow(); 1466 } catch (FJException success) { 1467 checkCompletedAbnormally(f, success); 1468 } 1469 }}; 1470 testInvokeOnPool(singletonPool(), a); 1471 } 1472 1473 /** 1474 * invokeAll(t1, t2) invokes all task arguments 1475 */ 1476 public void testInvokeAll2Singleton() { 1477 RecursiveAction a = new CheckedRecursiveAction() { 1478 protected void realCompute() { 1479 AsyncFib f = new AsyncFib(8); 1480 AsyncFib g = new AsyncFib(9); 1481 invokeAll(f, g); 1482 assertEquals(21, f.number); 1483 assertEquals(34, g.number); 1484 checkCompletedNormally(f); 1485 checkCompletedNormally(g); 1486 }}; 1487 testInvokeOnPool(singletonPool(), a); 1488 } 1489 1490 /** 1491 * invokeAll(tasks) with 1 argument invokes task 1492 */ 1493 public void testInvokeAll1Singleton() { 1494 RecursiveAction a = new CheckedRecursiveAction() { 1495 protected void realCompute() { 1496 AsyncFib f = new AsyncFib(8); 1497 invokeAll(f); 1498 checkCompletedNormally(f); 1499 assertEquals(21, f.number); 1500 }}; 1501 testInvokeOnPool(singletonPool(), a); 1502 } 1503 1504 /** 1505 * invokeAll(tasks) with > 2 argument invokes tasks 1506 */ 1507 public void testInvokeAll3Singleton() { 1508 RecursiveAction a = new CheckedRecursiveAction() { 1509 protected void realCompute() { 1510 AsyncFib f = new AsyncFib(8); 1511 AsyncFib g = new AsyncFib(9); 1512 AsyncFib h = new AsyncFib(7); 1513 invokeAll(f, g, h); 1514 assertEquals(21, f.number); 1515 assertEquals(34, g.number); 1516 assertEquals(13, h.number); 1517 checkCompletedNormally(f); 1518 checkCompletedNormally(g); 1519 checkCompletedNormally(h); 1520 }}; 1521 testInvokeOnPool(singletonPool(), a); 1522 } 1523 1524 /** 1525 * invokeAll(collection) invokes all tasks in the collection 1526 */ 1527 public void testInvokeAllCollectionSingleton() { 1528 RecursiveAction a = new CheckedRecursiveAction() { 1529 protected void realCompute() { 1530 AsyncFib f = new AsyncFib(8); 1531 AsyncFib g = new AsyncFib(9); 1532 AsyncFib h = new AsyncFib(7); 1533 HashSet set = new HashSet(); 1534 set.add(f); 1535 set.add(g); 1536 set.add(h); 1537 invokeAll(set); 1538 assertEquals(21, f.number); 1539 assertEquals(34, g.number); 1540 assertEquals(13, h.number); 1541 checkCompletedNormally(f); 1542 checkCompletedNormally(g); 1543 checkCompletedNormally(h); 1544 }}; 1545 testInvokeOnPool(singletonPool(), a); 1546 } 1547 1548 /** 1549 * invokeAll(tasks) with any null task throws NPE 1550 */ 1551 public void testInvokeAllNPESingleton() { 1552 RecursiveAction a = new CheckedRecursiveAction() { 1553 protected void realCompute() { 1554 AsyncFib f = new AsyncFib(8); 1555 AsyncFib g = new AsyncFib(9); 1556 AsyncFib h = null; 1557 try { 1558 invokeAll(f, g, h); 1559 shouldThrow(); 1560 } catch (NullPointerException success) {} 1561 }}; 1562 testInvokeOnPool(singletonPool(), a); 1563 } 1564 1565 /** 1566 * invokeAll(t1, t2) throw exception if any task does 1567 */ 1568 public void testAbnormalInvokeAll2Singleton() { 1569 RecursiveAction a = new CheckedRecursiveAction() { 1570 protected void realCompute() { 1571 AsyncFib f = new AsyncFib(8); 1572 FailingAsyncFib g = new FailingAsyncFib(9); 1573 ForkJoinTask[] tasks = { f, g }; 1574 Collections.shuffle(Arrays.asList(tasks)); 1575 try { 1576 invokeAll(tasks); 1577 shouldThrow(); 1578 } catch (FJException success) { 1579 checkCompletedAbnormally(g, success); 1580 } 1581 }}; 1582 testInvokeOnPool(singletonPool(), a); 1583 } 1584 1585 /** 1586 * invokeAll(tasks) with 1 argument throws exception if task does 1587 */ 1588 public void testAbnormalInvokeAll1Singleton() { 1589 RecursiveAction a = new CheckedRecursiveAction() { 1590 protected void realCompute() { 1591 FailingAsyncFib g = new FailingAsyncFib(9); 1592 try { 1593 invokeAll(g); 1594 shouldThrow(); 1595 } catch (FJException success) { 1596 checkCompletedAbnormally(g, success); 1597 } 1598 }}; 1599 testInvokeOnPool(singletonPool(), a); 1600 } 1601 1602 /** 1603 * invokeAll(tasks) with > 2 argument throws exception if any task does 1604 */ 1605 public void testAbnormalInvokeAll3Singleton() { 1606 RecursiveAction a = new CheckedRecursiveAction() { 1607 protected void realCompute() { 1608 AsyncFib f = new AsyncFib(8); 1609 FailingAsyncFib g = new FailingAsyncFib(9); 1610 AsyncFib h = new AsyncFib(7); 1611 ForkJoinTask[] tasks = { f, g, h }; 1612 Collections.shuffle(Arrays.asList(tasks)); 1613 try { 1614 invokeAll(tasks); 1615 shouldThrow(); 1616 } catch (FJException success) { 1617 checkCompletedAbnormally(g, success); 1618 } 1619 }}; 1620 testInvokeOnPool(singletonPool(), a); 1621 } 1622 1623 /** 1624 * invokeAll(collection) throws exception if any task does 1625 */ 1626 public void testAbnormalInvokeAllCollectionSingleton() { 1627 RecursiveAction a = new CheckedRecursiveAction() { 1628 protected void realCompute() { 1629 FailingAsyncFib f = new FailingAsyncFib(8); 1630 AsyncFib g = new AsyncFib(9); 1631 AsyncFib h = new AsyncFib(7); 1632 ForkJoinTask[] tasks = { f, g, h }; 1633 List taskList = Arrays.asList(tasks); 1634 Collections.shuffle(taskList); 1635 try { 1636 invokeAll(taskList); 1637 shouldThrow(); 1638 } catch (FJException success) { 1639 checkCompletedAbnormally(f, success); 1640 } 1641 }}; 1642 testInvokeOnPool(singletonPool(), a); 1643 } 1644 1645 /** 1646 * ForkJoinTask.quietlyComplete returns when task completes 1647 * normally without setting a value. The most recent value 1648 * established by setRawResult(V) (or null by default) is returned 1649 * from invoke. 1650 */ 1651 public void testQuietlyComplete() { 1652 RecursiveAction a = new CheckedRecursiveAction() { 1653 protected void realCompute() { 1654 AsyncFib f = new AsyncFib(8); 1655 f.quietlyComplete(); 1656 assertEquals(8, f.number); 1657 checkCompletedNormally(f); 1658 }}; 1659 testInvokeOnPool(mainPool(), a); 1660 } 1661 1662 } 1663