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