ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.3
Committed: Mon Jul 22 18:01:03 2013 UTC (10 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.2: +0 -2 lines
Log Message:
whitespace

File Contents

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