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