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