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.SECONDS; 10 11 import java.util.HashSet; 12 import java.util.concurrent.CancellationException; 13 import java.util.concurrent.ExecutionException; 14 import java.util.concurrent.ForkJoinPool; 15 import java.util.concurrent.ForkJoinTask; 16 import java.util.concurrent.RecursiveTask; 17 import java.util.concurrent.TimeoutException; 18 19 import junit.framework.Test; 20 import junit.framework.TestSuite; 21 22 public class RecursiveTaskTest extends JSR166TestCase { 23 24 // android-note: Removed because the CTS runner does a bad job of 25 // retrying tests that have suite() declarations. 26 // 27 // public static void main(String[] args) { 28 // main(suite(), args); 29 // } 30 // public static Test suite() { 31 // return new TestSuite(...); 32 // } 33 34 private static ForkJoinPool mainPool() { 35 return new ForkJoinPool(); 36 } 37 38 private static ForkJoinPool singletonPool() { 39 return new ForkJoinPool(1); 40 } 41 42 private static ForkJoinPool asyncSingletonPool() { 43 return new ForkJoinPool(1, 44 ForkJoinPool.defaultForkJoinWorkerThreadFactory, 45 null, true); 46 } 47 48 private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) { 49 try { 50 checkNotDone(a); 51 52 T result = pool.invoke(a); 53 54 checkCompletedNormally(a, result); 55 return result; 56 } finally { 57 joinPool(pool); 58 } 59 } 60 61 void checkNotDone(RecursiveTask a) { 62 assertFalse(a.isDone()); 63 assertFalse(a.isCompletedNormally()); 64 assertFalse(a.isCompletedAbnormally()); 65 assertFalse(a.isCancelled()); 66 assertNull(a.getException()); 67 assertNull(a.getRawResult()); 68 69 if (! ForkJoinTask.inForkJoinPool()) { 70 Thread.currentThread().interrupt(); 71 try { 72 a.get(); 73 shouldThrow(); 74 } catch (InterruptedException success) { 75 } catch (Throwable fail) { threadUnexpectedException(fail); } 76 77 Thread.currentThread().interrupt(); 78 try { 79 a.get(5L, SECONDS); 80 shouldThrow(); 81 } catch (InterruptedException success) { 82 } catch (Throwable fail) { threadUnexpectedException(fail); } 83 } 84 85 try { 86 a.get(0L, SECONDS); 87 shouldThrow(); 88 } catch (TimeoutException success) { 89 } catch (Throwable fail) { threadUnexpectedException(fail); } 90 } 91 92 <T> void checkCompletedNormally(RecursiveTask<T> a, T expected) { 93 assertTrue(a.isDone()); 94 assertFalse(a.isCancelled()); 95 assertTrue(a.isCompletedNormally()); 96 assertFalse(a.isCompletedAbnormally()); 97 assertNull(a.getException()); 98 assertSame(expected, a.getRawResult()); 99 assertSame(expected, a.join()); 100 assertFalse(a.cancel(false)); 101 assertFalse(a.cancel(true)); 102 try { 103 assertSame(expected, a.get()); 104 } catch (Throwable fail) { threadUnexpectedException(fail); } 105 try { 106 assertSame(expected, a.get(5L, SECONDS)); 107 } catch (Throwable fail) { threadUnexpectedException(fail); } 108 } 109 110 /** 111 * Waits for the task to complete, and checks that when it does, 112 * it will have an Integer result equals to the given int. 113 */ 114 void checkCompletesNormally(RecursiveTask<Integer> a, int expected) { 115 Integer r = a.join(); 116 assertEquals(expected, (int) r); 117 checkCompletedNormally(a, r); 118 } 119 120 /** 121 * Like checkCompletesNormally, but verifies that the task has 122 * already completed. 123 */ 124 void checkCompletedNormally(RecursiveTask<Integer> a, int expected) { 125 Integer r = a.getRawResult(); 126 assertEquals(expected, (int) r); 127 checkCompletedNormally(a, r); 128 } 129 130 void checkCancelled(RecursiveTask a) { 131 assertTrue(a.isDone()); 132 assertTrue(a.isCancelled()); 133 assertFalse(a.isCompletedNormally()); 134 assertTrue(a.isCompletedAbnormally()); 135 assertTrue(a.getException() instanceof CancellationException); 136 assertNull(a.getRawResult()); 137 138 try { 139 a.join(); 140 shouldThrow(); 141 } catch (CancellationException success) { 142 } catch (Throwable fail) { threadUnexpectedException(fail); } 143 144 try { 145 a.get(); 146 shouldThrow(); 147 } catch (CancellationException success) { 148 } catch (Throwable fail) { threadUnexpectedException(fail); } 149 150 try { 151 a.get(5L, SECONDS); 152 shouldThrow(); 153 } catch (CancellationException success) { 154 } catch (Throwable fail) { threadUnexpectedException(fail); } 155 } 156 157 void checkCompletedAbnormally(RecursiveTask a, Throwable t) { 158 assertTrue(a.isDone()); 159 assertFalse(a.isCancelled()); 160 assertFalse(a.isCompletedNormally()); 161 assertTrue(a.isCompletedAbnormally()); 162 assertSame(t.getClass(), a.getException().getClass()); 163 assertNull(a.getRawResult()); 164 assertFalse(a.cancel(false)); 165 assertFalse(a.cancel(true)); 166 167 try { 168 a.join(); 169 shouldThrow(); 170 } catch (Throwable expected) { 171 assertSame(t.getClass(), expected.getClass()); 172 } 173 174 try { 175 a.get(); 176 shouldThrow(); 177 } catch (ExecutionException success) { 178 assertSame(t.getClass(), success.getCause().getClass()); 179 } catch (Throwable fail) { threadUnexpectedException(fail); } 180 181 try { 182 a.get(5L, SECONDS); 183 shouldThrow(); 184 } catch (ExecutionException success) { 185 assertSame(t.getClass(), success.getCause().getClass()); 186 } catch (Throwable fail) { threadUnexpectedException(fail); } 187 } 188 189 public static final class FJException extends RuntimeException { 190 public FJException() { super(); } 191 } 192 193 // An invalid return value for Fib 194 static final Integer NoResult = Integer.valueOf(-17); 195 196 // A simple recursive task for testing 197 final class FibTask extends CheckedRecursiveTask<Integer> { 198 final int number; 199 FibTask(int n) { number = n; } 200 public Integer realCompute() { 201 int n = number; 202 if (n <= 1) 203 return n; 204 FibTask f1 = new FibTask(n - 1); 205 f1.fork(); 206 return (new FibTask(n - 2)).compute() + f1.join(); 207 } 208 209 public void publicSetRawResult(Integer result) { 210 setRawResult(result); 211 } 212 } 213 214 // A recursive action failing in base case 215 final class FailingFibTask extends RecursiveTask<Integer> { 216 final int number; 217 int result; 218 FailingFibTask(int n) { number = n; } 219 public Integer compute() { 220 int n = number; 221 if (n <= 1) 222 throw new FJException(); 223 FailingFibTask f1 = new FailingFibTask(n - 1); 224 f1.fork(); 225 return (new FibTask(n - 2)).compute() + f1.join(); 226 } 227 } 228 229 /** 230 * invoke returns value when task completes normally. 231 * isCompletedAbnormally and isCancelled return false for normally 232 * completed tasks. getRawResult of a completed non-null task 233 * returns value; 234 */ 235 public void testInvoke() { 236 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 237 public Integer realCompute() { 238 FibTask f = new FibTask(8); 239 Integer r = f.invoke(); 240 assertEquals(21, (int) r); 241 checkCompletedNormally(f, r); 242 return r; 243 }}; 244 assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 245 } 246 247 /** 248 * quietlyInvoke task returns when task completes normally. 249 * isCompletedAbnormally and isCancelled return false for normally 250 * completed tasks 251 */ 252 public void testQuietlyInvoke() { 253 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 254 public Integer realCompute() { 255 FibTask f = new FibTask(8); 256 f.quietlyInvoke(); 257 checkCompletedNormally(f, 21); 258 return NoResult; 259 }}; 260 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 261 } 262 263 /** 264 * join of a forked task returns when task completes 265 */ 266 public void testForkJoin() { 267 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 268 public Integer realCompute() { 269 FibTask f = new FibTask(8); 270 assertSame(f, f.fork()); 271 Integer r = f.join(); 272 assertEquals(21, (int) r); 273 checkCompletedNormally(f, r); 274 return r; 275 }}; 276 assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 277 } 278 279 /** 280 * get of a forked task returns when task completes 281 */ 282 public void testForkGet() { 283 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 284 public Integer realCompute() throws Exception { 285 FibTask f = new FibTask(8); 286 assertSame(f, f.fork()); 287 Integer r = f.get(); 288 assertEquals(21, (int) r); 289 checkCompletedNormally(f, r); 290 return r; 291 }}; 292 assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 293 } 294 295 /** 296 * timed get of a forked task returns when task completes 297 */ 298 public void testForkTimedGet() { 299 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 300 public Integer realCompute() throws Exception { 301 FibTask f = new FibTask(8); 302 assertSame(f, f.fork()); 303 Integer r = f.get(5L, SECONDS); 304 assertEquals(21, (int) r); 305 checkCompletedNormally(f, r); 306 return r; 307 }}; 308 assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 309 } 310 311 /** 312 * quietlyJoin of a forked task returns when task completes 313 */ 314 public void testForkQuietlyJoin() { 315 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 316 public Integer realCompute() { 317 FibTask f = new FibTask(8); 318 assertSame(f, f.fork()); 319 f.quietlyJoin(); 320 Integer r = f.getRawResult(); 321 assertEquals(21, (int) r); 322 checkCompletedNormally(f, r); 323 return r; 324 }}; 325 assertEquals(21, (int) testInvokeOnPool(mainPool(), a)); 326 } 327 328 /** 329 * helpQuiesce returns when tasks are complete. 330 * getQueuedTaskCount returns 0 when quiescent 331 */ 332 public void testForkHelpQuiesce() { 333 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 334 public Integer realCompute() { 335 FibTask f = new FibTask(8); 336 assertSame(f, f.fork()); 337 helpQuiesce(); 338 assertEquals(0, getQueuedTaskCount()); 339 checkCompletedNormally(f, 21); 340 return NoResult; 341 }}; 342 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 343 } 344 345 /** 346 * invoke task throws exception when task completes abnormally 347 */ 348 public void testAbnormalInvoke() { 349 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 350 public Integer realCompute() { 351 FailingFibTask f = new FailingFibTask(8); 352 try { 353 f.invoke(); 354 shouldThrow(); 355 } catch (FJException success) { 356 checkCompletedAbnormally(f, success); 357 } 358 return NoResult; 359 }}; 360 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 361 } 362 363 /** 364 * quietlyInvoke task returns when task completes abnormally 365 */ 366 public void testAbnormalQuietlyInvoke() { 367 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 368 public Integer realCompute() { 369 FailingFibTask f = new FailingFibTask(8); 370 f.quietlyInvoke(); 371 assertTrue(f.getException() instanceof FJException); 372 checkCompletedAbnormally(f, f.getException()); 373 return NoResult; 374 }}; 375 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 376 } 377 378 /** 379 * join of a forked task throws exception when task completes abnormally 380 */ 381 public void testAbnormalForkJoin() { 382 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 383 public Integer realCompute() { 384 FailingFibTask f = new FailingFibTask(8); 385 assertSame(f, f.fork()); 386 try { 387 Integer r = f.join(); 388 shouldThrow(); 389 } catch (FJException success) { 390 checkCompletedAbnormally(f, success); 391 } 392 return NoResult; 393 }}; 394 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 395 } 396 397 /** 398 * get of a forked task throws exception when task completes abnormally 399 */ 400 public void testAbnormalForkGet() { 401 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 402 public Integer realCompute() throws Exception { 403 FailingFibTask f = new FailingFibTask(8); 404 assertSame(f, f.fork()); 405 try { 406 Integer r = f.get(); 407 shouldThrow(); 408 } catch (ExecutionException success) { 409 Throwable cause = success.getCause(); 410 assertTrue(cause instanceof FJException); 411 checkCompletedAbnormally(f, cause); 412 } 413 return NoResult; 414 }}; 415 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 416 } 417 418 /** 419 * timed get of a forked task throws exception when task completes abnormally 420 */ 421 public void testAbnormalForkTimedGet() { 422 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 423 public Integer realCompute() throws Exception { 424 FailingFibTask f = new FailingFibTask(8); 425 assertSame(f, f.fork()); 426 try { 427 Integer r = f.get(5L, SECONDS); 428 shouldThrow(); 429 } catch (ExecutionException success) { 430 Throwable cause = success.getCause(); 431 assertTrue(cause instanceof FJException); 432 checkCompletedAbnormally(f, cause); 433 } 434 return NoResult; 435 }}; 436 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 437 } 438 439 /** 440 * quietlyJoin of a forked task returns when task completes abnormally 441 */ 442 public void testAbnormalForkQuietlyJoin() { 443 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 444 public Integer realCompute() { 445 FailingFibTask f = new FailingFibTask(8); 446 assertSame(f, f.fork()); 447 f.quietlyJoin(); 448 assertTrue(f.getException() instanceof FJException); 449 checkCompletedAbnormally(f, f.getException()); 450 return NoResult; 451 }}; 452 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 453 } 454 455 /** 456 * invoke task throws exception when task cancelled 457 */ 458 public void testCancelledInvoke() { 459 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 460 public Integer realCompute() { 461 FibTask f = new FibTask(8); 462 assertTrue(f.cancel(true)); 463 try { 464 Integer r = f.invoke(); 465 shouldThrow(); 466 } catch (CancellationException success) { 467 checkCancelled(f); 468 } 469 return NoResult; 470 }}; 471 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 472 } 473 474 /** 475 * join of a forked task throws exception when task cancelled 476 */ 477 public void testCancelledForkJoin() { 478 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 479 public Integer realCompute() { 480 FibTask f = new FibTask(8); 481 assertTrue(f.cancel(true)); 482 assertSame(f, f.fork()); 483 try { 484 Integer r = f.join(); 485 shouldThrow(); 486 } catch (CancellationException success) { 487 checkCancelled(f); 488 } 489 return NoResult; 490 }}; 491 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 492 } 493 494 /** 495 * get of a forked task throws exception when task cancelled 496 */ 497 public void testCancelledForkGet() { 498 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 499 public Integer realCompute() throws Exception { 500 FibTask f = new FibTask(8); 501 assertTrue(f.cancel(true)); 502 assertSame(f, f.fork()); 503 try { 504 Integer r = f.get(); 505 shouldThrow(); 506 } catch (CancellationException success) { 507 checkCancelled(f); 508 } 509 return NoResult; 510 }}; 511 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 512 } 513 514 /** 515 * timed get of a forked task throws exception when task cancelled 516 */ 517 public void testCancelledForkTimedGet() { 518 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 519 public Integer realCompute() throws Exception { 520 FibTask f = new FibTask(8); 521 assertTrue(f.cancel(true)); 522 assertSame(f, f.fork()); 523 try { 524 Integer r = f.get(5L, SECONDS); 525 shouldThrow(); 526 } catch (CancellationException success) { 527 checkCancelled(f); 528 } 529 return NoResult; 530 }}; 531 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 532 } 533 534 /** 535 * quietlyJoin of a forked task returns when task cancelled 536 */ 537 public void testCancelledForkQuietlyJoin() { 538 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 539 public Integer realCompute() { 540 FibTask f = new FibTask(8); 541 assertTrue(f.cancel(true)); 542 assertSame(f, f.fork()); 543 f.quietlyJoin(); 544 checkCancelled(f); 545 return NoResult; 546 }}; 547 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 548 } 549 550 /** 551 * getPool of executing task returns its pool 552 */ 553 public void testGetPool() { 554 final ForkJoinPool mainPool = mainPool(); 555 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 556 public Integer realCompute() { 557 assertSame(mainPool, getPool()); 558 return NoResult; 559 }}; 560 assertSame(NoResult, testInvokeOnPool(mainPool, a)); 561 } 562 563 /** 564 * getPool of non-FJ task returns null 565 */ 566 public void testGetPool2() { 567 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 568 public Integer realCompute() { 569 assertNull(getPool()); 570 return NoResult; 571 }}; 572 assertSame(NoResult, a.invoke()); 573 } 574 575 /** 576 * inForkJoinPool of executing task returns true 577 */ 578 public void testInForkJoinPool() { 579 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 580 public Integer realCompute() { 581 assertTrue(inForkJoinPool()); 582 return NoResult; 583 }}; 584 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 585 } 586 587 /** 588 * inForkJoinPool of non-FJ task returns false 589 */ 590 public void testInForkJoinPool2() { 591 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 592 public Integer realCompute() { 593 assertFalse(inForkJoinPool()); 594 return NoResult; 595 }}; 596 assertSame(NoResult, a.invoke()); 597 } 598 599 /** 600 * The value set by setRawResult is returned by getRawResult 601 */ 602 public void testSetRawResult() { 603 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 604 public Integer realCompute() { 605 setRawResult(NoResult); 606 assertSame(NoResult, getRawResult()); 607 return NoResult; 608 } 609 }; 610 assertSame(NoResult, a.invoke()); 611 } 612 613 /** 614 * A reinitialized normally completed task may be re-invoked 615 */ 616 public void testReinitialize() { 617 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 618 public Integer realCompute() { 619 FibTask f = new FibTask(8); 620 checkNotDone(f); 621 622 for (int i = 0; i < 3; i++) { 623 Integer r = f.invoke(); 624 assertEquals(21, (int) r); 625 checkCompletedNormally(f, r); 626 f.reinitialize(); 627 f.publicSetRawResult(null); 628 checkNotDone(f); 629 } 630 return NoResult; 631 }}; 632 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 633 } 634 635 /** 636 * A reinitialized abnormally completed task may be re-invoked 637 */ 638 public void testReinitializeAbnormal() { 639 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 640 public Integer realCompute() { 641 FailingFibTask f = new FailingFibTask(8); 642 checkNotDone(f); 643 644 for (int i = 0; i < 3; i++) { 645 try { 646 f.invoke(); 647 shouldThrow(); 648 } catch (FJException success) { 649 checkCompletedAbnormally(f, success); 650 } 651 f.reinitialize(); 652 checkNotDone(f); 653 } 654 return NoResult; 655 }}; 656 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 657 } 658 659 /** 660 * invoke task throws exception after invoking completeExceptionally 661 */ 662 public void testCompleteExceptionally() { 663 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 664 public Integer realCompute() { 665 FibTask f = new FibTask(8); 666 f.completeExceptionally(new FJException()); 667 try { 668 Integer r = f.invoke(); 669 shouldThrow(); 670 } catch (FJException success) { 671 checkCompletedAbnormally(f, success); 672 } 673 return NoResult; 674 }}; 675 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 676 } 677 678 /** 679 * invoke task suppresses execution invoking complete 680 */ 681 public void testComplete() { 682 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 683 public Integer realCompute() { 684 FibTask f = new FibTask(8); 685 f.complete(NoResult); 686 Integer r = f.invoke(); 687 assertSame(NoResult, r); 688 checkCompletedNormally(f, NoResult); 689 return r; 690 }}; 691 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 692 } 693 694 /** 695 * invokeAll(t1, t2) invokes all task arguments 696 */ 697 public void testInvokeAll2() { 698 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 699 public Integer realCompute() { 700 FibTask f = new FibTask(8); 701 FibTask g = new FibTask(9); 702 invokeAll(f, g); 703 checkCompletedNormally(f, 21); 704 checkCompletedNormally(g, 34); 705 return NoResult; 706 }}; 707 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 708 } 709 710 /** 711 * invokeAll(tasks) with 1 argument invokes task 712 */ 713 public void testInvokeAll1() { 714 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 715 public Integer realCompute() { 716 FibTask f = new FibTask(8); 717 invokeAll(f); 718 checkCompletedNormally(f, 21); 719 return NoResult; 720 }}; 721 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 722 } 723 724 /** 725 * invokeAll(tasks) with > 2 argument invokes tasks 726 */ 727 public void testInvokeAll3() { 728 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 729 public Integer realCompute() { 730 FibTask f = new FibTask(8); 731 FibTask g = new FibTask(9); 732 FibTask h = new FibTask(7); 733 invokeAll(f, g, h); 734 assertTrue(f.isDone()); 735 assertTrue(g.isDone()); 736 assertTrue(h.isDone()); 737 checkCompletedNormally(f, 21); 738 checkCompletedNormally(g, 34); 739 checkCompletedNormally(h, 13); 740 return NoResult; 741 }}; 742 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 743 } 744 745 /** 746 * invokeAll(collection) invokes all tasks in the collection 747 */ 748 public void testInvokeAllCollection() { 749 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 750 public Integer realCompute() { 751 FibTask f = new FibTask(8); 752 FibTask g = new FibTask(9); 753 FibTask h = new FibTask(7); 754 HashSet set = new HashSet(); 755 set.add(f); 756 set.add(g); 757 set.add(h); 758 invokeAll(set); 759 assertTrue(f.isDone()); 760 assertTrue(g.isDone()); 761 assertTrue(h.isDone()); 762 checkCompletedNormally(f, 21); 763 checkCompletedNormally(g, 34); 764 checkCompletedNormally(h, 13); 765 return NoResult; 766 }}; 767 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 768 } 769 770 /** 771 * invokeAll(tasks) with any null task throws NPE 772 */ 773 public void testInvokeAllNPE() { 774 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 775 public Integer realCompute() { 776 FibTask f = new FibTask(8); 777 FibTask g = new FibTask(9); 778 FibTask h = null; 779 try { 780 invokeAll(f, g, h); 781 shouldThrow(); 782 } catch (NullPointerException success) {} 783 return NoResult; 784 }}; 785 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 786 } 787 788 /** 789 * invokeAll(t1, t2) throw exception if any task does 790 */ 791 public void testAbnormalInvokeAll2() { 792 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 793 public Integer realCompute() { 794 FibTask f = new FibTask(8); 795 FailingFibTask g = new FailingFibTask(9); 796 try { 797 invokeAll(f, g); 798 shouldThrow(); 799 } catch (FJException success) { 800 checkCompletedAbnormally(g, success); 801 } 802 return NoResult; 803 }}; 804 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 805 } 806 807 /** 808 * invokeAll(tasks) with 1 argument throws exception if task does 809 */ 810 public void testAbnormalInvokeAll1() { 811 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 812 public Integer realCompute() { 813 FailingFibTask g = new FailingFibTask(9); 814 try { 815 invokeAll(g); 816 shouldThrow(); 817 } catch (FJException success) { 818 checkCompletedAbnormally(g, success); 819 } 820 return NoResult; 821 }}; 822 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 823 } 824 825 /** 826 * invokeAll(tasks) with > 2 argument throws exception if any task does 827 */ 828 public void testAbnormalInvokeAll3() { 829 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 830 public Integer realCompute() { 831 FibTask f = new FibTask(8); 832 FailingFibTask g = new FailingFibTask(9); 833 FibTask h = new FibTask(7); 834 try { 835 invokeAll(f, g, h); 836 shouldThrow(); 837 } catch (FJException success) { 838 checkCompletedAbnormally(g, success); 839 } 840 return NoResult; 841 }}; 842 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 843 } 844 845 /** 846 * invokeAll(collection) throws exception if any task does 847 */ 848 public void testAbnormalInvokeAllCollection() { 849 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 850 public Integer realCompute() { 851 FailingFibTask f = new FailingFibTask(8); 852 FibTask g = new FibTask(9); 853 FibTask h = new FibTask(7); 854 HashSet set = new HashSet(); 855 set.add(f); 856 set.add(g); 857 set.add(h); 858 try { 859 invokeAll(set); 860 shouldThrow(); 861 } catch (FJException success) { 862 checkCompletedAbnormally(f, success); 863 } 864 return NoResult; 865 }}; 866 assertSame(NoResult, testInvokeOnPool(mainPool(), a)); 867 } 868 869 /** 870 * tryUnfork returns true for most recent unexecuted task, 871 * and suppresses execution 872 */ 873 public void testTryUnfork() { 874 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 875 public Integer realCompute() { 876 FibTask g = new FibTask(9); 877 assertSame(g, g.fork()); 878 FibTask f = new FibTask(8); 879 assertSame(f, f.fork()); 880 assertTrue(f.tryUnfork()); 881 helpQuiesce(); 882 checkNotDone(f); 883 checkCompletedNormally(g, 34); 884 return NoResult; 885 }}; 886 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 887 } 888 889 /** 890 * getSurplusQueuedTaskCount returns > 0 when 891 * there are more tasks than threads 892 */ 893 public void testGetSurplusQueuedTaskCount() { 894 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 895 public Integer realCompute() { 896 FibTask h = new FibTask(7); 897 assertSame(h, h.fork()); 898 FibTask g = new FibTask(9); 899 assertSame(g, g.fork()); 900 FibTask f = new FibTask(8); 901 assertSame(f, f.fork()); 902 assertTrue(getSurplusQueuedTaskCount() > 0); 903 helpQuiesce(); 904 assertEquals(0, getSurplusQueuedTaskCount()); 905 checkCompletedNormally(f, 21); 906 checkCompletedNormally(g, 34); 907 checkCompletedNormally(h, 13); 908 return NoResult; 909 }}; 910 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 911 } 912 913 /** 914 * peekNextLocalTask returns most recent unexecuted task. 915 */ 916 public void testPeekNextLocalTask() { 917 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 918 public Integer realCompute() { 919 FibTask g = new FibTask(9); 920 assertSame(g, g.fork()); 921 FibTask f = new FibTask(8); 922 assertSame(f, f.fork()); 923 assertSame(f, peekNextLocalTask()); 924 checkCompletesNormally(f, 21); 925 helpQuiesce(); 926 checkCompletedNormally(g, 34); 927 return NoResult; 928 }}; 929 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 930 } 931 932 /** 933 * pollNextLocalTask returns most recent unexecuted task 934 * without executing it 935 */ 936 public void testPollNextLocalTask() { 937 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 938 public Integer realCompute() { 939 FibTask g = new FibTask(9); 940 assertSame(g, g.fork()); 941 FibTask f = new FibTask(8); 942 assertSame(f, f.fork()); 943 assertSame(f, pollNextLocalTask()); 944 helpQuiesce(); 945 checkNotDone(f); 946 checkCompletedNormally(g, 34); 947 return NoResult; 948 }}; 949 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 950 } 951 952 /** 953 * pollTask returns an unexecuted task without executing it 954 */ 955 public void testPollTask() { 956 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 957 public Integer realCompute() { 958 FibTask g = new FibTask(9); 959 assertSame(g, g.fork()); 960 FibTask f = new FibTask(8); 961 assertSame(f, f.fork()); 962 assertSame(f, pollTask()); 963 helpQuiesce(); 964 checkNotDone(f); 965 checkCompletedNormally(g, 34); 966 return NoResult; 967 }}; 968 assertSame(NoResult, testInvokeOnPool(singletonPool(), a)); 969 } 970 971 /** 972 * peekNextLocalTask returns least recent unexecuted task in async mode 973 */ 974 public void testPeekNextLocalTaskAsync() { 975 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 976 public Integer realCompute() { 977 FibTask g = new FibTask(9); 978 assertSame(g, g.fork()); 979 FibTask f = new FibTask(8); 980 assertSame(f, f.fork()); 981 assertSame(g, peekNextLocalTask()); 982 assertEquals(21, (int) f.join()); 983 helpQuiesce(); 984 checkCompletedNormally(f, 21); 985 checkCompletedNormally(g, 34); 986 return NoResult; 987 }}; 988 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a)); 989 } 990 991 /** 992 * pollNextLocalTask returns least recent unexecuted task without 993 * executing it, in async mode 994 */ 995 public void testPollNextLocalTaskAsync() { 996 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 997 public Integer realCompute() { 998 FibTask g = new FibTask(9); 999 assertSame(g, g.fork()); 1000 FibTask f = new FibTask(8); 1001 assertSame(f, f.fork()); 1002 assertSame(g, pollNextLocalTask()); 1003 helpQuiesce(); 1004 checkCompletedNormally(f, 21); 1005 checkNotDone(g); 1006 return NoResult; 1007 }}; 1008 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a)); 1009 } 1010 1011 /** 1012 * pollTask returns an unexecuted task without executing it, in 1013 * async mode 1014 */ 1015 public void testPollTaskAsync() { 1016 RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() { 1017 public Integer realCompute() { 1018 FibTask g = new FibTask(9); 1019 assertSame(g, g.fork()); 1020 FibTask f = new FibTask(8); 1021 assertSame(f, f.fork()); 1022 assertSame(g, pollTask()); 1023 helpQuiesce(); 1024 checkCompletedNormally(f, 21); 1025 checkNotDone(g); 1026 return NoResult; 1027 }}; 1028 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a)); 1029 } 1030 1031 } 1032