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