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