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