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