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