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