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