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(RecursiveTaskTest.class);
     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 (PoolCleaner cleaner = cleaner(pool)) {
     50             checkNotDone(a);
     51 
     52             T result = pool.invoke(a);
     53 
     54             checkCompletedNormally(a, result);
     55             return result;
     56         }
     57     }
     58 
     59     void checkNotDone(RecursiveTask a) {
     60         assertFalse(a.isDone());
     61         assertFalse(a.isCompletedNormally());
     62         assertFalse(a.isCompletedAbnormally());
     63         assertFalse(a.isCancelled());
     64         assertNull(a.getException());
     65         assertNull(a.getRawResult());
     66 
     67         if (! ForkJoinTask.inForkJoinPool()) {
     68             Thread.currentThread().interrupt();
     69             try {
     70                 a.get();
     71                 shouldThrow();
     72             } catch (InterruptedException success) {
     73             } catch (Throwable fail) { threadUnexpectedException(fail); }
     74 
     75             Thread.currentThread().interrupt();
     76             try {
     77                 a.get(5L, SECONDS);
     78                 shouldThrow();
     79             } catch (InterruptedException success) {
     80             } catch (Throwable fail) { threadUnexpectedException(fail); }
     81         }
     82 
     83         try {
     84             a.get(0L, SECONDS);
     85             shouldThrow();
     86         } catch (TimeoutException success) {
     87         } catch (Throwable fail) { threadUnexpectedException(fail); }
     88     }
     89 
     90     <T> void checkCompletedNormally(RecursiveTask<T> a, T expected) {
     91         assertTrue(a.isDone());
     92         assertFalse(a.isCancelled());
     93         assertTrue(a.isCompletedNormally());
     94         assertFalse(a.isCompletedAbnormally());
     95         assertNull(a.getException());
     96         assertSame(expected, a.getRawResult());
     97         assertSame(expected, a.join());
     98         assertFalse(a.cancel(false));
     99         assertFalse(a.cancel(true));
    100         try {
    101             assertSame(expected, a.get());
    102         } catch (Throwable fail) { threadUnexpectedException(fail); }
    103         try {
    104             assertSame(expected, a.get(5L, SECONDS));
    105         } catch (Throwable fail) { threadUnexpectedException(fail); }
    106     }
    107 
    108     /**
    109      * Waits for the task to complete, and checks that when it does,
    110      * it will have an Integer result equals to the given int.
    111      */
    112     void checkCompletesNormally(RecursiveTask<Integer> a, int expected) {
    113         Integer r = a.join();
    114         assertEquals(expected, (int) r);
    115         checkCompletedNormally(a, r);
    116     }
    117 
    118     /**
    119      * Like checkCompletesNormally, but verifies that the task has
    120      * already completed.
    121      */
    122     void checkCompletedNormally(RecursiveTask<Integer> a, int expected) {
    123         Integer r = a.getRawResult();
    124         assertEquals(expected, (int) r);
    125         checkCompletedNormally(a, r);
    126     }
    127 
    128     void checkCancelled(RecursiveTask a) {
    129         assertTrue(a.isDone());
    130         assertTrue(a.isCancelled());
    131         assertFalse(a.isCompletedNormally());
    132         assertTrue(a.isCompletedAbnormally());
    133         assertTrue(a.getException() instanceof CancellationException);
    134         assertNull(a.getRawResult());
    135 
    136         try {
    137             a.join();
    138             shouldThrow();
    139         } catch (CancellationException success) {
    140         } catch (Throwable fail) { threadUnexpectedException(fail); }
    141 
    142         try {
    143             a.get();
    144             shouldThrow();
    145         } catch (CancellationException success) {
    146         } catch (Throwable fail) { threadUnexpectedException(fail); }
    147 
    148         try {
    149             a.get(5L, SECONDS);
    150             shouldThrow();
    151         } catch (CancellationException success) {
    152         } catch (Throwable fail) { threadUnexpectedException(fail); }
    153     }
    154 
    155     void checkCompletedAbnormally(RecursiveTask a, Throwable t) {
    156         assertTrue(a.isDone());
    157         assertFalse(a.isCancelled());
    158         assertFalse(a.isCompletedNormally());
    159         assertTrue(a.isCompletedAbnormally());
    160         assertSame(t.getClass(), a.getException().getClass());
    161         assertNull(a.getRawResult());
    162         assertFalse(a.cancel(false));
    163         assertFalse(a.cancel(true));
    164 
    165         try {
    166             a.join();
    167             shouldThrow();
    168         } catch (Throwable expected) {
    169             assertSame(t.getClass(), expected.getClass());
    170         }
    171 
    172         try {
    173             a.get();
    174             shouldThrow();
    175         } catch (ExecutionException success) {
    176             assertSame(t.getClass(), success.getCause().getClass());
    177         } catch (Throwable fail) { threadUnexpectedException(fail); }
    178 
    179         try {
    180             a.get(5L, SECONDS);
    181             shouldThrow();
    182         } catch (ExecutionException success) {
    183             assertSame(t.getClass(), success.getCause().getClass());
    184         } catch (Throwable fail) { threadUnexpectedException(fail); }
    185     }
    186 
    187     public static final class FJException extends RuntimeException {
    188         public FJException() { super(); }
    189     }
    190 
    191     // An invalid return value for Fib
    192     static final Integer NoResult = Integer.valueOf(-17);
    193 
    194     // A simple recursive task for testing
    195     final class FibTask extends CheckedRecursiveTask<Integer> {
    196         final int number;
    197         FibTask(int n) { number = n; }
    198         public Integer realCompute() {
    199             int n = number;
    200             if (n <= 1)
    201                 return n;
    202             FibTask f1 = new FibTask(n - 1);
    203             f1.fork();
    204             return (new FibTask(n - 2)).compute() + f1.join();
    205         }
    206 
    207         public void publicSetRawResult(Integer result) {
    208             setRawResult(result);
    209         }
    210     }
    211 
    212     // A recursive action failing in base case
    213     final class FailingFibTask extends RecursiveTask<Integer> {
    214         final int number;
    215         int result;
    216         FailingFibTask(int n) { number = n; }
    217         public Integer compute() {
    218             int n = number;
    219             if (n <= 1)
    220                 throw new FJException();
    221             FailingFibTask f1 = new FailingFibTask(n - 1);
    222             f1.fork();
    223             return (new FibTask(n - 2)).compute() + f1.join();
    224         }
    225     }
    226 
    227     /**
    228      * invoke returns value when task completes normally.
    229      * isCompletedAbnormally and isCancelled return false for normally
    230      * completed tasks. getRawResult of a completed non-null task
    231      * returns value;
    232      */
    233     public void testInvoke() {
    234         RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
    235             public Integer realCompute() {
    236                 FibTask f = new FibTask(8);
    237                 Integer r = f.invoke();
    238                 assertEquals(21, (int) r);
    239                 checkCompletedNormally(f, r);
    240                 return r;
    241             }};
    242         assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
    243     }
    244 
    245     /**
    246      * quietlyInvoke task returns when task completes normally.
    247      * isCompletedAbnormally and isCancelled return false for normally
    248      * completed tasks
    249      */
    250     public void testQuietlyInvoke() {
    251         RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
    252             public Integer realCompute() {
    253                 FibTask f = new FibTask(8);
    254                 f.quietlyInvoke();
    255                 checkCompletedNormally(f, 21);
    256                 return NoResult;
    257             }};
    258         assertSame(NoResult, testInvokeOnPool(mainPool(), a));
    259     }
    260 
    261     /**
    262      * join of a forked task returns when task completes
    263      */
    264     public void testForkJoin() {
    265         RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
    266             public Integer realCompute() {
    267                 FibTask f = new FibTask(8);
    268                 assertSame(f, f.fork());
    269                 Integer r = f.join();
    270                 assertEquals(21, (int) r);
    271                 checkCompletedNormally(f, r);
    272                 return r;
    273             }};
    274         assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
    275     }
    276 
    277     /**
    278      * get of a forked task returns when task completes
    279      */
    280     public void testForkGet() {
    281         RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
    282             public Integer realCompute() throws Exception {
    283                 FibTask f = new FibTask(8);
    284                 assertSame(f, f.fork());
    285                 Integer r = f.get();
    286                 assertEquals(21, (int) r);
    287                 checkCompletedNormally(f, r);
    288                 return r;
    289             }};
    290         assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
    291     }
    292 
    293     /**
    294      * timed get of a forked task returns when task completes
    295      */
    296     public void testForkTimedGet() {
    297         RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
    298             public Integer realCompute() throws Exception {
    299                 FibTask f = new FibTask(8);
    300                 assertSame(f, f.fork());
    301                 Integer r = f.get(5L, SECONDS);
    302                 assertEquals(21, (int) r);
    303                 checkCompletedNormally(f, r);
    304                 return r;
    305             }};
    306         assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
    307     }
    308 
    309     /**
    310      * quietlyJoin of a forked task returns when task completes
    311      */
    312     public void testForkQuietlyJoin() {
    313         RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
    314             public Integer realCompute() {
    315                 FibTask f = new FibTask(8);
    316                 assertSame(f, f.fork());
    317                 f.quietlyJoin();
    318                 Integer r = f.getRawResult();
    319                 assertEquals(21, (int) r);
    320                 checkCompletedNormally(f, r);
    321                 return r;
    322             }};
    323         assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
    324     }
    325 
    326     /**
    327      * helpQuiesce returns when tasks are complete.
    328      * getQueuedTaskCount returns 0 when quiescent
    329      */
    330     public void testForkHelpQuiesce() {
    331         RecursiveTask<Integer> a = new CheckedRecursiveTask<Integer>() {
    332             public Integer realCompute() {
    333                 FibTask f = new FibTask(8);
    334                 assertSame(f, f.fork());
    335                 helpQuiesce();
    336                 while (!f.isDone()) // wait out race
    337                     ;
    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