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