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