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