ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/RecursiveActionTest.java
(Generate patch)

Comparing jsr166/src/test/tck/RecursiveActionTest.java (file contents):
Revision 1.2 by jsr166, Fri Jul 31 23:37:31 2009 UTC vs.
Revision 1.49 by jsr166, Sat Mar 18 18:20:00 2017 UTC

# Line 1 | Line 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/licenses/publicdomain
4 > * http://creativecommons.org/publicdomain/zero/1.0/
5   */
6 import junit.framework.*;
7 import java.util.concurrent.*;
8 import java.util.*;
6  
7 + import static java.util.concurrent.TimeUnit.SECONDS;
8 +
9 + import java.util.Arrays;
10 + import java.util.HashSet;
11 + import java.util.concurrent.CancellationException;
12 + import java.util.concurrent.ExecutionException;
13 + import java.util.concurrent.ForkJoinPool;
14 + import java.util.concurrent.ForkJoinTask;
15 + import java.util.concurrent.ForkJoinWorkerThread;
16 + import java.util.concurrent.RecursiveAction;
17 + import java.util.concurrent.SynchronousQueue;
18 + import java.util.concurrent.ThreadLocalRandom;
19 + import java.util.concurrent.TimeoutException;
20 +
21 + import junit.framework.Test;
22 + import junit.framework.TestSuite;
23  
24   public class RecursiveActionTest extends JSR166TestCase {
25  
26      public static void main(String[] args) {
27 <        junit.textui.TestRunner.run (suite());
27 >        main(suite(), args);
28      }
29 +
30      public static Test suite() {
31 <        return new TestSuite(RecursiveActionTest.class);
31 >        return new TestSuite(RecursiveActionTest.class);
32 >    }
33 >
34 >    private static ForkJoinPool mainPool() {
35 >        return new ForkJoinPool();
36 >    }
37 >
38 >    private static ForkJoinPool singletonPool() {
39 >        return new ForkJoinPool(1);
40 >    }
41 >
42 >    private static ForkJoinPool asyncSingletonPool() {
43 >        return new ForkJoinPool(1,
44 >                                ForkJoinPool.defaultForkJoinWorkerThreadFactory,
45 >                                null, true);
46      }
47  
48 <    static final ForkJoinPool mainPool = new ForkJoinPool();
49 <    static final ForkJoinPool singletonPool = new ForkJoinPool(1);
50 <    static final ForkJoinPool asyncSingletonPool = new ForkJoinPool(1);
51 <    static {
52 <        asyncSingletonPool.setAsyncMode(true);
48 >    private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
49 >        try (PoolCleaner cleaner = cleaner(pool)) {
50 >            checkNotDone(a);
51 >
52 >            assertNull(pool.invoke(a));
53 >
54 >            checkCompletedNormally(a);
55 >        }
56      }
57  
58 <    static final class FJException extends RuntimeException {
59 <        FJException() { super(); }
58 >    void checkNotDone(RecursiveAction a) {
59 >        assertFalse(a.isDone());
60 >        assertFalse(a.isCompletedNormally());
61 >        assertFalse(a.isCompletedAbnormally());
62 >        assertFalse(a.isCancelled());
63 >        assertNull(a.getException());
64 >        assertNull(a.getRawResult());
65 >
66 >        if (! ForkJoinTask.inForkJoinPool()) {
67 >            Thread.currentThread().interrupt();
68 >            try {
69 >                a.get();
70 >                shouldThrow();
71 >            } catch (InterruptedException success) {
72 >            } catch (Throwable fail) { threadUnexpectedException(fail); }
73 >
74 >            Thread.currentThread().interrupt();
75 >            try {
76 >                a.get(5L, SECONDS);
77 >                shouldThrow();
78 >            } catch (InterruptedException success) {
79 >            } catch (Throwable fail) { threadUnexpectedException(fail); }
80 >        }
81 >
82 >        try {
83 >            a.get(0L, SECONDS);
84 >            shouldThrow();
85 >        } catch (TimeoutException success) {
86 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
87 >    }
88 >
89 >    void checkCompletedNormally(RecursiveAction a) {
90 >        assertTrue(a.isDone());
91 >        assertFalse(a.isCancelled());
92 >        assertTrue(a.isCompletedNormally());
93 >        assertFalse(a.isCompletedAbnormally());
94 >        assertNull(a.getException());
95 >        assertNull(a.getRawResult());
96 >        assertNull(a.join());
97 >        assertFalse(a.cancel(false));
98 >        assertFalse(a.cancel(true));
99 >        try {
100 >            assertNull(a.get());
101 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
102 >        try {
103 >            assertNull(a.get(5L, SECONDS));
104 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
105 >    }
106 >
107 >    void checkCancelled(RecursiveAction a) {
108 >        assertTrue(a.isDone());
109 >        assertTrue(a.isCancelled());
110 >        assertFalse(a.isCompletedNormally());
111 >        assertTrue(a.isCompletedAbnormally());
112 >        assertTrue(a.getException() instanceof CancellationException);
113 >        assertNull(a.getRawResult());
114 >
115 >        try {
116 >            a.join();
117 >            shouldThrow();
118 >        } catch (CancellationException success) {
119 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
120 >
121 >        try {
122 >            a.get();
123 >            shouldThrow();
124 >        } catch (CancellationException success) {
125 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
126 >
127 >        try {
128 >            a.get(5L, SECONDS);
129 >            shouldThrow();
130 >        } catch (CancellationException success) {
131 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
132 >    }
133 >
134 >    void checkCompletedAbnormally(RecursiveAction a, Throwable t) {
135 >        assertTrue(a.isDone());
136 >        assertFalse(a.isCancelled());
137 >        assertFalse(a.isCompletedNormally());
138 >        assertTrue(a.isCompletedAbnormally());
139 >        assertSame(t.getClass(), a.getException().getClass());
140 >        assertNull(a.getRawResult());
141 >        assertFalse(a.cancel(false));
142 >        assertFalse(a.cancel(true));
143 >
144 >        try {
145 >            a.join();
146 >            shouldThrow();
147 >        } catch (Throwable expected) {
148 >            assertSame(expected.getClass(), t.getClass());
149 >        }
150 >
151 >        try {
152 >            a.get();
153 >            shouldThrow();
154 >        } catch (ExecutionException success) {
155 >            assertSame(t.getClass(), success.getCause().getClass());
156 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
157 >
158 >        try {
159 >            a.get(5L, SECONDS);
160 >            shouldThrow();
161 >        } catch (ExecutionException success) {
162 >            assertSame(t.getClass(), success.getCause().getClass());
163 >        } catch (Throwable fail) { threadUnexpectedException(fail); }
164 >    }
165 >
166 >    public static final class FJException extends RuntimeException {
167 >        public FJException() { super(); }
168 >        public FJException(Throwable cause) { super(cause); }
169      }
170  
171 <    // A simple recursive action for testing
172 <    static final class FibAction extends RecursiveAction {
171 >    /** A simple recursive action for testing. */
172 >    final class FibAction extends CheckedRecursiveAction {
173          final int number;
174          int result;
175          FibAction(int n) { number = n; }
176 <        public void compute() {
176 >        protected void realCompute() {
177              int n = number;
178              if (n <= 1)
179                  result = n;
# Line 46 | Line 186 | public class RecursiveActionTest extends
186          }
187      }
188  
189 <    // A recursive action failing in base case
189 >    /** A recursive action failing in base case. */
190      static final class FailingFibAction extends RecursiveAction {
191          final int number;
192          int result;
# Line 68 | Line 208 | public class RecursiveActionTest extends
208       * invoke returns when task completes normally.
209       * isCompletedAbnormally and isCancelled return false for normally
210       * completed tasks. getRawResult of a RecursiveAction returns null;
71     *
211       */
212      public void testInvoke() {
213 <        RecursiveAction a = new RecursiveAction() {
214 <                public void compute() {
215 <                    FibAction f = new FibAction(8);
216 <                    f.invoke();
217 <                    threadAssertTrue(f.result == 21);
218 <                    threadAssertTrue(f.isDone());
219 <                    threadAssertFalse(f.isCancelled());
220 <                    threadAssertFalse(f.isCompletedAbnormally());
82 <                    threadAssertTrue(f.getRawResult() == null);
83 <                }
84 <            };
85 <        mainPool.invoke(a);
213 >        RecursiveAction a = new CheckedRecursiveAction() {
214 >            protected void realCompute() {
215 >                FibAction f = new FibAction(8);
216 >                assertNull(f.invoke());
217 >                assertEquals(21, f.result);
218 >                checkCompletedNormally(f);
219 >            }};
220 >        testInvokeOnPool(mainPool(), a);
221      }
222  
223      /**
# Line 91 | Line 226 | public class RecursiveActionTest extends
226       * completed tasks
227       */
228      public void testQuietlyInvoke() {
229 <        RecursiveAction a = new RecursiveAction() {
230 <                public void compute() {
231 <                    FibAction f = new FibAction(8);
232 <                    f.quietlyInvoke();
233 <                    threadAssertTrue(f.result == 21);
234 <                    threadAssertTrue(f.isDone());
235 <                    threadAssertFalse(f.isCancelled());
236 <                    threadAssertFalse(f.isCompletedAbnormally());
102 <                    threadAssertTrue(f.getRawResult() == null);
103 <                }
104 <            };
105 <        mainPool.invoke(a);
229 >        RecursiveAction a = new CheckedRecursiveAction() {
230 >            protected void realCompute() {
231 >                FibAction f = new FibAction(8);
232 >                f.quietlyInvoke();
233 >                assertEquals(21, f.result);
234 >                checkCompletedNormally(f);
235 >            }};
236 >        testInvokeOnPool(mainPool(), a);
237      }
238  
239      /**
240       * join of a forked task returns when task completes
241       */
242      public void testForkJoin() {
243 <        RecursiveAction a = new RecursiveAction() {
244 <                public void compute() {
245 <                    FibAction f = new FibAction(8);
246 <                    f.fork();
243 >        RecursiveAction a = new CheckedRecursiveAction() {
244 >            protected void realCompute() {
245 >                FibAction f = new FibAction(8);
246 >                assertSame(f, f.fork());
247 >                assertNull(f.join());
248 >                assertEquals(21, f.result);
249 >                checkCompletedNormally(f);
250 >            }};
251 >        testInvokeOnPool(mainPool(), a);
252 >    }
253 >
254 >    /**
255 >     * join/quietlyJoin of a forked task succeeds in the presence of interrupts
256 >     */
257 >    public void testJoinIgnoresInterrupts() {
258 >        RecursiveAction a = new CheckedRecursiveAction() {
259 >            protected void realCompute() {
260 >                FibAction f = new FibAction(8);
261 >                final Thread currentThread = Thread.currentThread();
262 >
263 >                // test join()
264 >                assertSame(f, f.fork());
265 >                currentThread.interrupt();
266 >                assertNull(f.join());
267 >                Thread.interrupted();
268 >                assertEquals(21, f.result);
269 >                checkCompletedNormally(f);
270 >
271 >                f = new FibAction(8);
272 >                f.cancel(true);
273 >                assertSame(f, f.fork());
274 >                currentThread.interrupt();
275 >                try {
276 >                    f.join();
277 >                    shouldThrow();
278 >                } catch (CancellationException success) {
279 >                    Thread.interrupted();
280 >                    checkCancelled(f);
281 >                }
282 >
283 >                f = new FibAction(8);
284 >                f.completeExceptionally(new FJException());
285 >                assertSame(f, f.fork());
286 >                currentThread.interrupt();
287 >                try {
288 >                    f.join();
289 >                    shouldThrow();
290 >                } catch (FJException success) {
291 >                    Thread.interrupted();
292 >                    checkCompletedAbnormally(f, success);
293 >                }
294 >
295 >                // test quietlyJoin()
296 >                f = new FibAction(8);
297 >                assertSame(f, f.fork());
298 >                currentThread.interrupt();
299 >                f.quietlyJoin();
300 >                Thread.interrupted();
301 >                assertEquals(21, f.result);
302 >                checkCompletedNormally(f);
303 >
304 >                f = new FibAction(8);
305 >                f.cancel(true);
306 >                assertSame(f, f.fork());
307 >                currentThread.interrupt();
308 >                f.quietlyJoin();
309 >                Thread.interrupted();
310 >                checkCancelled(f);
311 >
312 >                f = new FibAction(8);
313 >                f.completeExceptionally(new FJException());
314 >                assertSame(f, f.fork());
315 >                currentThread.interrupt();
316 >                f.quietlyJoin();
317 >                Thread.interrupted();
318 >                checkCompletedAbnormally(f, f.getException());
319 >            }};
320 >        testInvokeOnPool(mainPool(), a);
321 >        a.reinitialize();
322 >        testInvokeOnPool(singletonPool(), a);
323 >    }
324 >
325 >    /**
326 >     * join/quietlyJoin of a forked task when not in ForkJoinPool
327 >     * succeeds in the presence of interrupts
328 >     */
329 >    public void testJoinIgnoresInterruptsOutsideForkJoinPool() {
330 >        final SynchronousQueue<FibAction[]> sq =
331 >            new SynchronousQueue<FibAction[]>();
332 >        RecursiveAction a = new CheckedRecursiveAction() {
333 >            protected void realCompute() throws InterruptedException {
334 >                FibAction[] fibActions = new FibAction[6];
335 >                for (int i = 0; i < fibActions.length; i++)
336 >                    fibActions[i] = new FibAction(8);
337 >
338 >                fibActions[1].cancel(false);
339 >                fibActions[2].completeExceptionally(new FJException());
340 >                fibActions[4].cancel(true);
341 >                fibActions[5].completeExceptionally(new FJException());
342 >
343 >                for (int i = 0; i < fibActions.length; i++)
344 >                    fibActions[i].fork();
345 >
346 >                sq.put(fibActions);
347 >
348 >                helpQuiesce();
349 >            }};
350 >
351 >        Runnable r = new CheckedRunnable() {
352 >            public void realRun() throws InterruptedException {
353 >                FibAction[] fibActions = sq.take();
354 >                FibAction f;
355 >                final Thread currentThread = Thread.currentThread();
356 >
357 >                // test join() ------------
358 >
359 >                f = fibActions[0];
360 >                assertFalse(ForkJoinTask.inForkJoinPool());
361 >                currentThread.interrupt();
362 >                assertNull(f.join());
363 >                assertTrue(Thread.interrupted());
364 >                assertEquals(21, f.result);
365 >                checkCompletedNormally(f);
366 >
367 >                f = fibActions[1];
368 >                currentThread.interrupt();
369 >                try {
370                      f.join();
371 <                    threadAssertTrue(f.result == 21);
372 <                    threadAssertTrue(f.isDone());
373 <                    threadAssertTrue(f.getRawResult() == null);
371 >                    shouldThrow();
372 >                } catch (CancellationException success) {
373 >                    assertTrue(Thread.interrupted());
374 >                    checkCancelled(f);
375                  }
376 <            };
377 <        mainPool.invoke(a);
376 >
377 >                f = fibActions[2];
378 >                currentThread.interrupt();
379 >                try {
380 >                    f.join();
381 >                    shouldThrow();
382 >                } catch (FJException success) {
383 >                    assertTrue(Thread.interrupted());
384 >                    checkCompletedAbnormally(f, success);
385 >                }
386 >
387 >                // test quietlyJoin() ---------
388 >
389 >                f = fibActions[3];
390 >                currentThread.interrupt();
391 >                f.quietlyJoin();
392 >                assertTrue(Thread.interrupted());
393 >                assertEquals(21, f.result);
394 >                checkCompletedNormally(f);
395 >
396 >                f = fibActions[4];
397 >                currentThread.interrupt();
398 >                f.quietlyJoin();
399 >                assertTrue(Thread.interrupted());
400 >                checkCancelled(f);
401 >
402 >                f = fibActions[5];
403 >                currentThread.interrupt();
404 >                f.quietlyJoin();
405 >                assertTrue(Thread.interrupted());
406 >                assertTrue(f.getException() instanceof FJException);
407 >                checkCompletedAbnormally(f, f.getException());
408 >            }};
409 >
410 >        Thread t;
411 >
412 >        t = newStartedThread(r);
413 >        testInvokeOnPool(mainPool(), a);
414 >        awaitTermination(t);
415 >
416 >        a.reinitialize();
417 >        t = newStartedThread(r);
418 >        testInvokeOnPool(singletonPool(), a);
419 >        awaitTermination(t);
420      }
421  
422      /**
423       * get of a forked task returns when task completes
424       */
425      public void testForkGet() {
426 <        RecursiveAction a = new RecursiveAction() {
427 <                public void compute() {
428 <                    try {
429 <                        FibAction f = new FibAction(8);
430 <                        f.fork();
431 <                        f.get();
432 <                        threadAssertTrue(f.result == 21);
433 <                        threadAssertTrue(f.isDone());
434 <                    } catch (Exception ex) {
138 <                        unexpectedException();
139 <                    }
140 <                }
141 <            };
142 <        mainPool.invoke(a);
426 >        RecursiveAction a = new CheckedRecursiveAction() {
427 >            protected void realCompute() throws Exception {
428 >                FibAction f = new FibAction(8);
429 >                assertSame(f, f.fork());
430 >                assertNull(f.get());
431 >                assertEquals(21, f.result);
432 >                checkCompletedNormally(f);
433 >            }};
434 >        testInvokeOnPool(mainPool(), a);
435      }
436  
437      /**
438       * timed get of a forked task returns when task completes
439       */
440      public void testForkTimedGet() {
441 <        RecursiveAction a = new RecursiveAction() {
442 <                public void compute() {
443 <                    try {
444 <                        FibAction f = new FibAction(8);
445 <                        f.fork();
446 <                        f.get(5L, TimeUnit.SECONDS);
447 <                        threadAssertTrue(f.result == 21);
448 <                        threadAssertTrue(f.isDone());
449 <                    } catch (Exception ex) {
158 <                        unexpectedException();
159 <                    }
160 <                }
161 <            };
162 <        mainPool.invoke(a);
441 >        RecursiveAction a = new CheckedRecursiveAction() {
442 >            protected void realCompute() throws Exception {
443 >                FibAction f = new FibAction(8);
444 >                assertSame(f, f.fork());
445 >                assertNull(f.get(5L, SECONDS));
446 >                assertEquals(21, f.result);
447 >                checkCompletedNormally(f);
448 >            }};
449 >        testInvokeOnPool(mainPool(), a);
450      }
451  
452      /**
453       * timed get with null time unit throws NPE
454       */
455      public void testForkTimedGetNPE() {
456 <        RecursiveAction a = new RecursiveAction() {
457 <                public void compute() {
458 <                    try {
459 <                        FibAction f = new FibAction(8);
460 <                        f.fork();
461 <                        f.get(5L, null);
462 <                    } catch (NullPointerException success) {
463 <                    } catch (Exception ex) {
464 <                        unexpectedException();
465 <                    }
179 <                }
180 <            };
181 <        mainPool.invoke(a);
182 <    }
183 <
184 <    /**
185 <     * helpJoin of a forked task returns when task completes
186 <     */
187 <    public void testForkHelpJoin() {
188 <        RecursiveAction a = new RecursiveAction() {
189 <                public void compute() {
190 <                    FibAction f = new FibAction(8);
191 <                    f.fork();
192 <                    f.helpJoin();
193 <                    threadAssertTrue(f.result == 21);
194 <                    threadAssertTrue(f.isDone());
195 <                }
196 <            };
197 <        mainPool.invoke(a);
456 >        RecursiveAction a = new CheckedRecursiveAction() {
457 >            protected void realCompute() throws Exception {
458 >                FibAction f = new FibAction(8);
459 >                assertSame(f, f.fork());
460 >                try {
461 >                    f.get(5L, null);
462 >                    shouldThrow();
463 >                } catch (NullPointerException success) {}
464 >            }};
465 >        testInvokeOnPool(mainPool(), a);
466      }
467  
468      /**
469       * quietlyJoin of a forked task returns when task completes
470       */
471      public void testForkQuietlyJoin() {
472 <        RecursiveAction a = new RecursiveAction() {
473 <                public void compute() {
474 <                    FibAction f = new FibAction(8);
475 <                    f.fork();
476 <                    f.quietlyJoin();
477 <                    threadAssertTrue(f.result == 21);
478 <                    threadAssertTrue(f.isDone());
479 <                }
480 <            };
213 <        mainPool.invoke(a);
214 <    }
215 <
216 <
217 <    /**
218 <     * quietlyHelpJoin of a forked task returns when task completes
219 <     */
220 <    public void testForkQuietlyHelpJoin() {
221 <        RecursiveAction a = new RecursiveAction() {
222 <                public void compute() {
223 <                    FibAction f = new FibAction(8);
224 <                    f.fork();
225 <                    f.quietlyHelpJoin();
226 <                    threadAssertTrue(f.result == 21);
227 <                    threadAssertTrue(f.isDone());
228 <                }
229 <            };
230 <        mainPool.invoke(a);
472 >        RecursiveAction a = new CheckedRecursiveAction() {
473 >            protected void realCompute() {
474 >                FibAction f = new FibAction(8);
475 >                assertSame(f, f.fork());
476 >                f.quietlyJoin();
477 >                assertEquals(21, f.result);
478 >                checkCompletedNormally(f);
479 >            }};
480 >        testInvokeOnPool(mainPool(), a);
481      }
482  
233
483      /**
484       * helpQuiesce returns when tasks are complete.
485       * getQueuedTaskCount returns 0 when quiescent
486       */
487      public void testForkHelpQuiesce() {
488 <        RecursiveAction a = new RecursiveAction() {
489 <                public void compute() {
490 <                    FibAction f = new FibAction(8);
491 <                    f.fork();
492 <                    f.helpQuiesce();
493 <                    threadAssertTrue(f.result == 21);
494 <                    threadAssertTrue(f.isDone());
495 <                    threadAssertTrue(getQueuedTaskCount() == 0);
496 <                }
497 <            };
498 <        mainPool.invoke(a);
488 >        RecursiveAction a = new CheckedRecursiveAction() {
489 >            protected void realCompute() {
490 >                FibAction f = new FibAction(8);
491 >                assertSame(f, f.fork());
492 >                helpQuiesce();
493 >                while (!f.isDone()) // wait out race
494 >                    ;
495 >                assertEquals(21, f.result);
496 >                assertEquals(0, getQueuedTaskCount());
497 >                checkCompletedNormally(f);
498 >            }};
499 >        testInvokeOnPool(mainPool(), a);
500      }
501  
252
502      /**
503       * invoke task throws exception when task completes abnormally
504       */
505      public void testAbnormalInvoke() {
506 <        RecursiveAction a = new RecursiveAction() {
507 <                public void compute() {
508 <                    try {
509 <                        FailingFibAction f = new FailingFibAction(8);
510 <                        f.invoke();
511 <                        shouldThrow();
512 <                    } catch (FJException success) {
513 <                    }
506 >        RecursiveAction a = new CheckedRecursiveAction() {
507 >            protected void realCompute() {
508 >                FailingFibAction f = new FailingFibAction(8);
509 >                try {
510 >                    f.invoke();
511 >                    shouldThrow();
512 >                } catch (FJException success) {
513 >                    checkCompletedAbnormally(f, success);
514                  }
515 <            };
516 <        mainPool.invoke(a);
515 >            }};
516 >        testInvokeOnPool(mainPool(), a);
517      }
518  
519      /**
520 <     * quietelyInvoke task returns when task completes abnormally
520 >     * quietlyInvoke task returns when task completes abnormally
521       */
522      public void testAbnormalQuietlyInvoke() {
523 <        RecursiveAction a = new RecursiveAction() {
524 <                public void compute() {
525 <                    FailingFibAction f = new FailingFibAction(8);
526 <                    f.quietlyInvoke();
527 <                    threadAssertTrue(f.isDone());
528 <                }
529 <            };
530 <        mainPool.invoke(a);
523 >        RecursiveAction a = new CheckedRecursiveAction() {
524 >            protected void realCompute() {
525 >                FailingFibAction f = new FailingFibAction(8);
526 >                f.quietlyInvoke();
527 >                assertTrue(f.getException() instanceof FJException);
528 >                checkCompletedAbnormally(f, f.getException());
529 >            }};
530 >        testInvokeOnPool(mainPool(), a);
531      }
532  
533      /**
534       * join of a forked task throws exception when task completes abnormally
535       */
536      public void testAbnormalForkJoin() {
537 <        RecursiveAction a = new RecursiveAction() {
538 <                public void compute() {
539 <                    try {
540 <                        FailingFibAction f = new FailingFibAction(8);
541 <                        f.fork();
542 <                        f.join();
543 <                        shouldThrow();
544 <                    } catch (FJException success) {
545 <                    }
537 >        RecursiveAction a = new CheckedRecursiveAction() {
538 >            protected void realCompute() {
539 >                FailingFibAction f = new FailingFibAction(8);
540 >                assertSame(f, f.fork());
541 >                try {
542 >                    f.join();
543 >                    shouldThrow();
544 >                } catch (FJException success) {
545 >                    checkCompletedAbnormally(f, success);
546                  }
547 <            };
548 <        mainPool.invoke(a);
547 >            }};
548 >        testInvokeOnPool(mainPool(), a);
549      }
550  
551      /**
552       * get of a forked task throws exception when task completes abnormally
553       */
554      public void testAbnormalForkGet() {
555 <        RecursiveAction a = new RecursiveAction() {
556 <                public void compute() {
557 <                    try {
558 <                        FailingFibAction f = new FailingFibAction(8);
559 <                        f.fork();
560 <                        f.get();
561 <                        shouldThrow();
562 <                    } catch (Exception success) {
563 <                    }
555 >        RecursiveAction a = new CheckedRecursiveAction() {
556 >            protected void realCompute() throws Exception {
557 >                FailingFibAction f = new FailingFibAction(8);
558 >                assertSame(f, f.fork());
559 >                try {
560 >                    f.get();
561 >                    shouldThrow();
562 >                } catch (ExecutionException success) {
563 >                    Throwable cause = success.getCause();
564 >                    assertTrue(cause instanceof FJException);
565 >                    checkCompletedAbnormally(f, cause);
566                  }
567 <            };
568 <        mainPool.invoke(a);
567 >            }};
568 >        testInvokeOnPool(mainPool(), a);
569      }
570  
571      /**
572       * timed get of a forked task throws exception when task completes abnormally
573       */
574      public void testAbnormalForkTimedGet() {
575 <        RecursiveAction a = new RecursiveAction() {
576 <                public void compute() {
577 <                    try {
578 <                        FailingFibAction f = new FailingFibAction(8);
579 <                        f.fork();
580 <                        f.get(5L, TimeUnit.SECONDS);
581 <                        shouldThrow();
582 <                    } catch (Exception success) {
583 <                    }
584 <                }
585 <            };
335 <        mainPool.invoke(a);
336 <    }
337 <
338 <    /**
339 <     * join of a forked task throws exception when task completes abnormally
340 <     */
341 <    public void testAbnormalForkHelpJoin() {
342 <        RecursiveAction a = new RecursiveAction() {
343 <                public void compute() {
344 <                    try {
345 <                        FailingFibAction f = new FailingFibAction(8);
346 <                        f.fork();
347 <                        f.helpJoin();
348 <                        shouldThrow();
349 <                    } catch (FJException success) {
350 <                    }
351 <                }
352 <            };
353 <        mainPool.invoke(a);
354 <    }
355 <
356 <    /**
357 <     * quietlyHelpJoin of a forked task returns when task completes abnormally.
358 <     * getException of failed task returns its exception.
359 <     * isCompletedAbnormally of a failed task returns true.
360 <     * isCancelled of a failed uncancelled task returns false
361 <     */
362 <    public void testAbnormalForkQuietlyHelpJoin() {
363 <        RecursiveAction a = new RecursiveAction() {
364 <                public void compute() {
365 <                    FailingFibAction f = new FailingFibAction(8);
366 <                    f.fork();
367 <                    f.quietlyHelpJoin();
368 <                    threadAssertTrue(f.isDone());
369 <                    threadAssertTrue(f.isCompletedAbnormally());
370 <                    threadAssertFalse(f.isCancelled());
371 <                    threadAssertTrue(f.getException() instanceof FJException);
575 >        RecursiveAction a = new CheckedRecursiveAction() {
576 >            protected void realCompute() throws Exception {
577 >                FailingFibAction f = new FailingFibAction(8);
578 >                assertSame(f, f.fork());
579 >                try {
580 >                    f.get(5L, SECONDS);
581 >                    shouldThrow();
582 >                } catch (ExecutionException success) {
583 >                    Throwable cause = success.getCause();
584 >                    assertTrue(cause instanceof FJException);
585 >                    checkCompletedAbnormally(f, cause);
586                  }
587 <            };
588 <        mainPool.invoke(a);
587 >            }};
588 >        testInvokeOnPool(mainPool(), a);
589      }
590  
591      /**
592       * quietlyJoin of a forked task returns when task completes abnormally
593       */
594      public void testAbnormalForkQuietlyJoin() {
595 <        RecursiveAction a = new RecursiveAction() {
596 <                public void compute() {
597 <                    FailingFibAction f = new FailingFibAction(8);
598 <                    f.fork();
599 <                    f.quietlyJoin();
600 <                    threadAssertTrue(f.isDone());
601 <                    threadAssertTrue(f.isCompletedAbnormally());
602 <                    threadAssertTrue(f.getException() instanceof FJException);
603 <                }
390 <            };
391 <        mainPool.invoke(a);
595 >        RecursiveAction a = new CheckedRecursiveAction() {
596 >            protected void realCompute() {
597 >                FailingFibAction f = new FailingFibAction(8);
598 >                assertSame(f, f.fork());
599 >                f.quietlyJoin();
600 >                assertTrue(f.getException() instanceof FJException);
601 >                checkCompletedAbnormally(f, f.getException());
602 >            }};
603 >        testInvokeOnPool(mainPool(), a);
604      }
605  
606      /**
607       * invoke task throws exception when task cancelled
608       */
609      public void testCancelledInvoke() {
610 <        RecursiveAction a = new RecursiveAction() {
611 <                public void compute() {
612 <                    try {
613 <                        FibAction f = new FibAction(8);
614 <                        f.cancel(true);
615 <                        f.invoke();
616 <                        shouldThrow();
617 <                    } catch (CancellationException success) {
618 <                    }
610 >        RecursiveAction a = new CheckedRecursiveAction() {
611 >            protected void realCompute() {
612 >                FibAction f = new FibAction(8);
613 >                assertTrue(f.cancel(true));
614 >                try {
615 >                    f.invoke();
616 >                    shouldThrow();
617 >                } catch (CancellationException success) {
618 >                    checkCancelled(f);
619                  }
620 <            };
621 <        mainPool.invoke(a);
620 >            }};
621 >        testInvokeOnPool(mainPool(), a);
622      }
623  
624      /**
625       * join of a forked task throws exception when task cancelled
626       */
627      public void testCancelledForkJoin() {
628 <        RecursiveAction a = new RecursiveAction() {
629 <                public void compute() {
630 <                    try {
631 <                        FibAction f = new FibAction(8);
632 <                        f.cancel(true);
633 <                        f.fork();
634 <                        f.join();
635 <                        shouldThrow();
636 <                    } catch (CancellationException success) {
637 <                    }
628 >        RecursiveAction a = new CheckedRecursiveAction() {
629 >            protected void realCompute() {
630 >                FibAction f = new FibAction(8);
631 >                assertTrue(f.cancel(true));
632 >                assertSame(f, f.fork());
633 >                try {
634 >                    f.join();
635 >                    shouldThrow();
636 >                } catch (CancellationException success) {
637 >                    checkCancelled(f);
638                  }
639 <            };
640 <        mainPool.invoke(a);
639 >            }};
640 >        testInvokeOnPool(mainPool(), a);
641      }
642  
643      /**
644       * get of a forked task throws exception when task cancelled
645       */
646      public void testCancelledForkGet() {
647 <        RecursiveAction a = new RecursiveAction() {
648 <                public void compute() {
649 <                    try {
650 <                        FibAction f = new FibAction(8);
651 <                        f.cancel(true);
652 <                        f.fork();
653 <                        f.get();
654 <                        shouldThrow();
655 <                    } catch (Exception success) {
656 <                    }
647 >        RecursiveAction a = new CheckedRecursiveAction() {
648 >            protected void realCompute() throws Exception {
649 >                FibAction f = new FibAction(8);
650 >                assertTrue(f.cancel(true));
651 >                assertSame(f, f.fork());
652 >                try {
653 >                    f.get();
654 >                    shouldThrow();
655 >                } catch (CancellationException success) {
656 >                    checkCancelled(f);
657                  }
658 <            };
659 <        mainPool.invoke(a);
658 >            }};
659 >        testInvokeOnPool(mainPool(), a);
660      }
661  
662      /**
663       * timed get of a forked task throws exception when task cancelled
664       */
665      public void testCancelledForkTimedGet() {
666 <        RecursiveAction a = new RecursiveAction() {
667 <                public void compute() {
668 <                    try {
669 <                        FibAction f = new FibAction(8);
670 <                        f.cancel(true);
671 <                        f.fork();
672 <                        f.get(5L, TimeUnit.SECONDS);
673 <                        shouldThrow();
674 <                    } catch (Exception success) {
675 <                    }
464 <                }
465 <            };
466 <        mainPool.invoke(a);
467 <    }
468 <
469 <    /**
470 <     * join of a forked task throws exception when task cancelled
471 <     */
472 <    public void testCancelledForkHelpJoin() {
473 <        RecursiveAction a = new RecursiveAction() {
474 <                public void compute() {
475 <                    try {
476 <                        FibAction f = new FibAction(8);
477 <                        f.cancel(true);
478 <                        f.fork();
479 <                        f.helpJoin();
480 <                        shouldThrow();
481 <                    } catch (CancellationException success) {
482 <                    }
483 <                }
484 <            };
485 <        mainPool.invoke(a);
486 <    }
487 <
488 <    /**
489 <     * quietlyHelpJoin of a forked task returns when task cancelled.
490 <     * getException of cancelled task returns its exception.
491 <     * isCompletedAbnormally of a cancelled task returns true.
492 <     * isCancelled of a cancelled task returns true
493 <     */
494 <    public void testCancelledForkQuietlyHelpJoin() {
495 <        RecursiveAction a = new RecursiveAction() {
496 <                public void compute() {
497 <                    FibAction f = new FibAction(8);
498 <                    f.cancel(true);
499 <                    f.fork();
500 <                    f.quietlyHelpJoin();
501 <                    threadAssertTrue(f.isDone());
502 <                    threadAssertTrue(f.isCompletedAbnormally());
503 <                    threadAssertTrue(f.isCancelled());
504 <                    threadAssertTrue(f.getException() instanceof CancellationException);
666 >        RecursiveAction a = new CheckedRecursiveAction() {
667 >            protected void realCompute() throws Exception {
668 >                FibAction f = new FibAction(8);
669 >                assertTrue(f.cancel(true));
670 >                assertSame(f, f.fork());
671 >                try {
672 >                    f.get(5L, SECONDS);
673 >                    shouldThrow();
674 >                } catch (CancellationException success) {
675 >                    checkCancelled(f);
676                  }
677 <            };
678 <        mainPool.invoke(a);
677 >            }};
678 >        testInvokeOnPool(mainPool(), a);
679      }
680  
681      /**
682       * quietlyJoin of a forked task returns when task cancelled
683       */
684      public void testCancelledForkQuietlyJoin() {
685 <        RecursiveAction a = new RecursiveAction() {
686 <                public void compute() {
687 <                    FibAction f = new FibAction(8);
688 <                    f.cancel(true);
689 <                    f.fork();
690 <                    f.quietlyJoin();
691 <                    threadAssertTrue(f.isDone());
692 <                    threadAssertTrue(f.isCompletedAbnormally());
693 <                    threadAssertTrue(f.getException() instanceof CancellationException);
523 <                }
524 <            };
525 <        mainPool.invoke(a);
685 >        RecursiveAction a = new CheckedRecursiveAction() {
686 >            protected void realCompute() {
687 >                FibAction f = new FibAction(8);
688 >                assertTrue(f.cancel(true));
689 >                assertSame(f, f.fork());
690 >                f.quietlyJoin();
691 >                checkCancelled(f);
692 >            }};
693 >        testInvokeOnPool(mainPool(), a);
694      }
695  
696      /**
697       * getPool of executing task returns its pool
698       */
699      public void testGetPool() {
700 <        RecursiveAction a = new RecursiveAction() {
701 <                public void compute() {
702 <                    threadAssertTrue(getPool() == mainPool);
703 <                }
704 <            };
705 <        mainPool.invoke(a);
700 >        final ForkJoinPool mainPool = mainPool();
701 >        RecursiveAction a = new CheckedRecursiveAction() {
702 >            protected void realCompute() {
703 >                assertSame(mainPool, getPool());
704 >            }};
705 >        testInvokeOnPool(mainPool, a);
706      }
707  
708      /**
709       * getPool of non-FJ task returns null
710       */
711      public void testGetPool2() {
712 <        RecursiveAction a = new RecursiveAction() {
713 <                public void compute() {
714 <                    threadAssertTrue(getPool() == null);
715 <                }
716 <            };
549 <        a.invoke();
712 >        RecursiveAction a = new CheckedRecursiveAction() {
713 >            protected void realCompute() {
714 >                assertNull(getPool());
715 >            }};
716 >        assertNull(a.invoke());
717      }
718  
719      /**
720       * inForkJoinPool of executing task returns true
721       */
722      public void testInForkJoinPool() {
723 <        RecursiveAction a = new RecursiveAction() {
724 <                public void compute() {
725 <                    threadAssertTrue(inForkJoinPool());
726 <                }
727 <            };
561 <        mainPool.invoke(a);
723 >        RecursiveAction a = new CheckedRecursiveAction() {
724 >            protected void realCompute() {
725 >                assertTrue(inForkJoinPool());
726 >            }};
727 >        testInvokeOnPool(mainPool(), a);
728      }
729  
730      /**
731       * inForkJoinPool of non-FJ task returns false
732       */
733      public void testInForkJoinPool2() {
734 <        RecursiveAction a = new RecursiveAction() {
735 <                public void compute() {
736 <                    threadAssertTrue(!inForkJoinPool());
737 <                }
738 <            };
573 <        a.invoke();
734 >        RecursiveAction a = new CheckedRecursiveAction() {
735 >            protected void realCompute() {
736 >                assertFalse(inForkJoinPool());
737 >            }};
738 >        assertNull(a.invoke());
739      }
740  
741      /**
742       * getPool of current thread in pool returns its pool
743       */
744      public void testWorkerGetPool() {
745 <        RecursiveAction a = new RecursiveAction() {
746 <                public void compute() {
747 <                    ForkJoinWorkerThread w =
748 <                        (ForkJoinWorkerThread)(Thread.currentThread());
749 <                    threadAssertTrue(w.getPool() == mainPool);
750 <                }
751 <            };
752 <        mainPool.invoke(a);
745 >        final ForkJoinPool mainPool = mainPool();
746 >        RecursiveAction a = new CheckedRecursiveAction() {
747 >            protected void realCompute() {
748 >                ForkJoinWorkerThread w =
749 >                    (ForkJoinWorkerThread) Thread.currentThread();
750 >                assertSame(mainPool, w.getPool());
751 >            }};
752 >        testInvokeOnPool(mainPool, a);
753      }
754  
755      /**
756       * getPoolIndex of current thread in pool returns 0 <= value < poolSize
592     *
757       */
758      public void testWorkerGetPoolIndex() {
759 <        RecursiveAction a = new RecursiveAction() {
760 <                public void compute() {
761 <                    ForkJoinWorkerThread w =
762 <                        (ForkJoinWorkerThread)(Thread.currentThread());
763 <                    int idx = w.getPoolIndex();
764 <                    threadAssertTrue(idx >= 0);
765 <                    threadAssertTrue(idx < mainPool.getPoolSize());
766 <                }
767 <            };
768 <        mainPool.invoke(a);
759 >        final ForkJoinPool mainPool = mainPool();
760 >        RecursiveAction a = new CheckedRecursiveAction() {
761 >            protected void realCompute() {
762 >                ForkJoinWorkerThread w =
763 >                    (ForkJoinWorkerThread) Thread.currentThread();
764 >                assertTrue(w.getPoolIndex() >= 0);
765 >                // pool size can shrink after assigning index, so cannot check
766 >                // assertTrue(w.getPoolIndex() < mainPool.getPoolSize());
767 >            }};
768 >        testInvokeOnPool(mainPool, a);
769      }
770  
607
771      /**
772       * setRawResult(null) succeeds
773       */
774      public void testSetRawResult() {
775 <        RecursiveAction a = new RecursiveAction() {
776 <                public void compute() {
777 <                    setRawResult(null);
778 <                }
779 <            };
780 <        a.invoke();
775 >        RecursiveAction a = new CheckedRecursiveAction() {
776 >            protected void realCompute() {
777 >                setRawResult(null);
778 >                assertNull(getRawResult());
779 >            }};
780 >        assertNull(a.invoke());
781      }
782  
783      /**
784 <     * A reinitialized task may be re-invoked
784 >     * A reinitialized normally completed task may be re-invoked
785       */
786      public void testReinitialize() {
787 <        RecursiveAction a = new RecursiveAction() {
788 <                public void compute() {
789 <                    FibAction f = new FibAction(8);
790 <                    f.invoke();
791 <                    threadAssertTrue(f.result == 21);
792 <                    threadAssertTrue(f.isDone());
793 <                    threadAssertFalse(f.isCancelled());
794 <                    threadAssertFalse(f.isCompletedAbnormally());
787 >        RecursiveAction a = new CheckedRecursiveAction() {
788 >            protected void realCompute() {
789 >                FibAction f = new FibAction(8);
790 >                checkNotDone(f);
791 >
792 >                for (int i = 0; i < 3; i++) {
793 >                    assertNull(f.invoke());
794 >                    assertEquals(21, f.result);
795 >                    checkCompletedNormally(f);
796                      f.reinitialize();
797 <                    f.invoke();
634 <                    threadAssertTrue(f.result == 21);
797 >                    checkNotDone(f);
798                  }
799 <            };
800 <        mainPool.invoke(a);
799 >            }};
800 >        testInvokeOnPool(mainPool(), a);
801      }
802  
803      /**
804 <     * invoke task throws exception after invoking completeExceptionally
804 >     * A reinitialized abnormally completed task may be re-invoked
805       */
806 <    public void testCompleteExceptionally() {
807 <        RecursiveAction a = new RecursiveAction() {
808 <                public void compute() {
806 >    public void testReinitializeAbnormal() {
807 >        RecursiveAction a = new CheckedRecursiveAction() {
808 >            protected void realCompute() {
809 >                FailingFibAction f = new FailingFibAction(8);
810 >                checkNotDone(f);
811 >
812 >                for (int i = 0; i < 3; i++) {
813                      try {
647                        FibAction f = new FibAction(8);
648                        f.completeExceptionally(new FJException());
814                          f.invoke();
815                          shouldThrow();
816                      } catch (FJException success) {
817 +                        checkCompletedAbnormally(f, success);
818                      }
819 +                    f.reinitialize();
820 +                    checkNotDone(f);
821                  }
822 <            };
823 <        mainPool.invoke(a);
822 >            }};
823 >        testInvokeOnPool(mainPool(), a);
824      }
825  
826      /**
827 <     * invoke task suppresses execution invoking complete
827 >     * invoke task throws exception after invoking completeExceptionally
828       */
829 <    public void testComplete() {
830 <        RecursiveAction a = new RecursiveAction() {
831 <                public void compute() {
832 <                    FibAction f = new FibAction(8);
833 <                    f.complete(null);
829 >    public void testCompleteExceptionally() {
830 >        RecursiveAction a = new CheckedRecursiveAction() {
831 >            protected void realCompute() {
832 >                FibAction f = new FibAction(8);
833 >                f.completeExceptionally(new FJException());
834 >                try {
835                      f.invoke();
836 <                    threadAssertTrue(f.isDone());
837 <                    threadAssertTrue(f.result == 0);
836 >                    shouldThrow();
837 >                } catch (FJException success) {
838 >                    checkCompletedAbnormally(f, success);
839                  }
840 <            };
841 <        mainPool.invoke(a);
840 >            }};
841 >        testInvokeOnPool(mainPool(), a);
842 >    }
843 >
844 >    /**
845 >     * invoke task suppresses execution invoking complete
846 >     */
847 >    public void testComplete() {
848 >        RecursiveAction a = new CheckedRecursiveAction() {
849 >            protected void realCompute() {
850 >                FibAction f = new FibAction(8);
851 >                f.complete(null);
852 >                assertNull(f.invoke());
853 >                assertEquals(0, f.result);
854 >                checkCompletedNormally(f);
855 >            }};
856 >        testInvokeOnPool(mainPool(), a);
857      }
858  
859      /**
860       * invokeAll(t1, t2) invokes all task arguments
861       */
862      public void testInvokeAll2() {
863 <        RecursiveAction a = new RecursiveAction() {
864 <                public void compute() {
865 <                    FibAction f = new FibAction(8);
866 <                    FibAction g = new FibAction(9);
867 <                    invokeAll(f, g);
868 <                    threadAssertTrue(f.isDone());
869 <                    threadAssertTrue(f.result == 21);
870 <                    threadAssertTrue(g.isDone());
871 <                    threadAssertTrue(g.result == 34);
872 <                }
873 <            };
689 <        mainPool.invoke(a);
863 >        RecursiveAction a = new CheckedRecursiveAction() {
864 >            protected void realCompute() {
865 >                FibAction f = new FibAction(8);
866 >                FibAction g = new FibAction(9);
867 >                invokeAll(f, g);
868 >                checkCompletedNormally(f);
869 >                assertEquals(21, f.result);
870 >                checkCompletedNormally(g);
871 >                assertEquals(34, g.result);
872 >            }};
873 >        testInvokeOnPool(mainPool(), a);
874      }
875  
876      /**
877       * invokeAll(tasks) with 1 argument invokes task
878       */
879      public void testInvokeAll1() {
880 <        RecursiveAction a = new RecursiveAction() {
881 <                public void compute() {
882 <                    FibAction f = new FibAction(8);
883 <                    invokeAll(f);
884 <                    threadAssertTrue(f.isDone());
885 <                    threadAssertTrue(f.result == 21);
886 <                }
887 <            };
704 <        mainPool.invoke(a);
880 >        RecursiveAction a = new CheckedRecursiveAction() {
881 >            protected void realCompute() {
882 >                FibAction f = new FibAction(8);
883 >                invokeAll(f);
884 >                checkCompletedNormally(f);
885 >                assertEquals(21, f.result);
886 >            }};
887 >        testInvokeOnPool(mainPool(), a);
888      }
889  
890      /**
891       * invokeAll(tasks) with > 2 argument invokes tasks
892       */
893      public void testInvokeAll3() {
894 <        RecursiveAction a = new RecursiveAction() {
895 <                public void compute() {
896 <                    FibAction f = new FibAction(8);
897 <                    FibAction g = new FibAction(9);
898 <                    FibAction h = new FibAction(7);
899 <                    invokeAll(f, g, h);
900 <                    threadAssertTrue(f.isDone());
901 <                    threadAssertTrue(f.result == 21);
902 <                    threadAssertTrue(g.isDone());
903 <                    threadAssertTrue(g.result == 34);
904 <                    threadAssertTrue(h.isDone());
905 <                    threadAssertTrue(h.result == 13);
906 <                }
907 <            };
908 <        mainPool.invoke(a);
894 >        RecursiveAction a = new CheckedRecursiveAction() {
895 >            protected void realCompute() {
896 >                FibAction f = new FibAction(8);
897 >                FibAction g = new FibAction(9);
898 >                FibAction h = new FibAction(7);
899 >                invokeAll(f, g, h);
900 >                assertTrue(f.isDone());
901 >                assertTrue(g.isDone());
902 >                assertTrue(h.isDone());
903 >                checkCompletedNormally(f);
904 >                assertEquals(21, f.result);
905 >                checkCompletedNormally(g);
906 >                assertEquals(34, g.result);
907 >                checkCompletedNormally(g);
908 >                assertEquals(13, h.result);
909 >            }};
910 >        testInvokeOnPool(mainPool(), a);
911      }
912  
913      /**
914       * invokeAll(collection) invokes all tasks in the collection
915       */
916      public void testInvokeAllCollection() {
917 <        RecursiveAction a = new RecursiveAction() {
918 <                public void compute() {
919 <                    FibAction f = new FibAction(8);
920 <                    FibAction g = new FibAction(9);
921 <                    FibAction h = new FibAction(7);
922 <                    HashSet set = new HashSet();
923 <                    set.add(f);
924 <                    set.add(g);
925 <                    set.add(h);
926 <                    invokeAll(set);
927 <                    threadAssertTrue(f.isDone());
928 <                    threadAssertTrue(f.result == 21);
929 <                    threadAssertTrue(g.isDone());
930 <                    threadAssertTrue(g.result == 34);
931 <                    threadAssertTrue(h.isDone());
932 <                    threadAssertTrue(h.result == 13);
933 <                }
934 <            };
935 <        mainPool.invoke(a);
917 >        RecursiveAction a = new CheckedRecursiveAction() {
918 >            protected void realCompute() {
919 >                FibAction f = new FibAction(8);
920 >                FibAction g = new FibAction(9);
921 >                FibAction h = new FibAction(7);
922 >                HashSet set = new HashSet();
923 >                set.add(f);
924 >                set.add(g);
925 >                set.add(h);
926 >                invokeAll(set);
927 >                assertTrue(f.isDone());
928 >                assertTrue(g.isDone());
929 >                assertTrue(h.isDone());
930 >                checkCompletedNormally(f);
931 >                assertEquals(21, f.result);
932 >                checkCompletedNormally(g);
933 >                assertEquals(34, g.result);
934 >                checkCompletedNormally(g);
935 >                assertEquals(13, h.result);
936 >            }};
937 >        testInvokeOnPool(mainPool(), a);
938      }
939  
753
940      /**
941       * invokeAll(tasks) with any null task throws NPE
942       */
943      public void testInvokeAllNPE() {
944 <        RecursiveAction a = new RecursiveAction() {
945 <                public void compute() {
946 <                    try {
947 <                        FibAction f = new FibAction(8);
948 <                        FibAction g = new FibAction(9);
949 <                        FibAction h = null;
950 <                        invokeAll(f, g, h);
951 <                        shouldThrow();
952 <                    } catch (NullPointerException success) {
953 <                    }
954 <                }
769 <            };
770 <        mainPool.invoke(a);
944 >        RecursiveAction a = new CheckedRecursiveAction() {
945 >            protected void realCompute() {
946 >                FibAction f = new FibAction(8);
947 >                FibAction g = new FibAction(9);
948 >                FibAction h = null;
949 >                try {
950 >                    invokeAll(f, g, h);
951 >                    shouldThrow();
952 >                } catch (NullPointerException success) {}
953 >            }};
954 >        testInvokeOnPool(mainPool(), a);
955      }
956  
957      /**
958       * invokeAll(t1, t2) throw exception if any task does
959       */
960      public void testAbnormalInvokeAll2() {
961 <        RecursiveAction a = new RecursiveAction() {
962 <                public void compute() {
963 <                    try {
964 <                        FibAction f = new FibAction(8);
965 <                        FailingFibAction g = new FailingFibAction(9);
966 <                        invokeAll(f, g);
967 <                        shouldThrow();
968 <                    } catch (FJException success) {
969 <                    }
961 >        RecursiveAction a = new CheckedRecursiveAction() {
962 >            protected void realCompute() {
963 >                FibAction f = new FibAction(8);
964 >                FailingFibAction g = new FailingFibAction(9);
965 >                try {
966 >                    invokeAll(f, g);
967 >                    shouldThrow();
968 >                } catch (FJException success) {
969 >                    checkCompletedAbnormally(g, success);
970                  }
971 <            };
972 <        mainPool.invoke(a);
971 >            }};
972 >        testInvokeOnPool(mainPool(), a);
973      }
974  
975      /**
976       * invokeAll(tasks) with 1 argument throws exception if task does
977       */
978      public void testAbnormalInvokeAll1() {
979 <        RecursiveAction a = new RecursiveAction() {
980 <                public void compute() {
981 <                    try {
982 <                        FailingFibAction g = new FailingFibAction(9);
983 <                        invokeAll(g);
984 <                        shouldThrow();
985 <                    } catch (FJException success) {
986 <                    }
979 >        RecursiveAction a = new CheckedRecursiveAction() {
980 >            protected void realCompute() {
981 >                FailingFibAction g = new FailingFibAction(9);
982 >                try {
983 >                    invokeAll(g);
984 >                    shouldThrow();
985 >                } catch (FJException success) {
986 >                    checkCompletedAbnormally(g, success);
987                  }
988 <            };
989 <        mainPool.invoke(a);
988 >            }};
989 >        testInvokeOnPool(mainPool(), a);
990      }
991  
992      /**
993       * invokeAll(tasks) with > 2 argument throws exception if any task does
994       */
995      public void testAbnormalInvokeAll3() {
996 <        RecursiveAction a = new RecursiveAction() {
997 <                public void compute() {
998 <                    try {
999 <                        FibAction f = new FibAction(8);
1000 <                        FailingFibAction g = new FailingFibAction(9);
1001 <                        FibAction h = new FibAction(7);
1002 <                        invokeAll(f, g, h);
1003 <                        shouldThrow();
1004 <                    } catch (FJException success) {
1005 <                    }
996 >        RecursiveAction a = new CheckedRecursiveAction() {
997 >            protected void realCompute() {
998 >                FibAction f = new FibAction(8);
999 >                FailingFibAction g = new FailingFibAction(9);
1000 >                FibAction h = new FibAction(7);
1001 >                try {
1002 >                    invokeAll(f, g, h);
1003 >                    shouldThrow();
1004 >                } catch (FJException success) {
1005 >                    checkCompletedAbnormally(g, success);
1006                  }
1007 <            };
1008 <        mainPool.invoke(a);
1007 >            }};
1008 >        testInvokeOnPool(mainPool(), a);
1009      }
1010  
1011      /**
1012 <     * invokeAll(collection)  throws exception if any task does
1012 >     * invokeAll(collection) throws exception if any task does
1013       */
1014      public void testAbnormalInvokeAllCollection() {
1015 <        RecursiveAction a = new RecursiveAction() {
1016 <                public void compute() {
1017 <                    try {
1018 <                        FailingFibAction f = new FailingFibAction(8);
1019 <                        FibAction g = new FibAction(9);
1020 <                        FibAction h = new FibAction(7);
1021 <                        HashSet set = new HashSet();
1022 <                        set.add(f);
1023 <                        set.add(g);
1024 <                        set.add(h);
1025 <                        invokeAll(set);
1026 <                        shouldThrow();
1027 <                    } catch (FJException success) {
1028 <                    }
1015 >        RecursiveAction a = new CheckedRecursiveAction() {
1016 >            protected void realCompute() {
1017 >                FailingFibAction f = new FailingFibAction(8);
1018 >                FibAction g = new FibAction(9);
1019 >                FibAction h = new FibAction(7);
1020 >                HashSet set = new HashSet();
1021 >                set.add(f);
1022 >                set.add(g);
1023 >                set.add(h);
1024 >                try {
1025 >                    invokeAll(set);
1026 >                    shouldThrow();
1027 >                } catch (FJException success) {
1028 >                    checkCompletedAbnormally(f, success);
1029                  }
1030 <            };
1031 <        mainPool.invoke(a);
1030 >            }};
1031 >        testInvokeOnPool(mainPool(), a);
1032      }
1033  
1034      /**
# Line 852 | Line 1036 | public class RecursiveActionTest extends
1036       * and suppresses execution
1037       */
1038      public void testTryUnfork() {
1039 <        RecursiveAction a = new RecursiveAction() {
1040 <                public void compute() {
1041 <                    FibAction g = new FibAction(9);
1042 <                    g.fork();
1043 <                    FibAction f = new FibAction(8);
1044 <                    f.fork();
1045 <                    threadAssertTrue(f.tryUnfork());
1046 <                    helpQuiesce();
1047 <                    threadAssertFalse(f.isDone());
1048 <                    threadAssertTrue(g.isDone());
1049 <                }
1050 <            };
867 <        singletonPool.invoke(a);
1039 >        RecursiveAction a = new CheckedRecursiveAction() {
1040 >            protected void realCompute() {
1041 >                FibAction g = new FibAction(9);
1042 >                assertSame(g, g.fork());
1043 >                FibAction f = new FibAction(8);
1044 >                assertSame(f, f.fork());
1045 >                assertTrue(f.tryUnfork());
1046 >                helpQuiesce();
1047 >                checkNotDone(f);
1048 >                checkCompletedNormally(g);
1049 >            }};
1050 >        testInvokeOnPool(singletonPool(), a);
1051      }
1052  
1053      /**
# Line 872 | Line 1055 | public class RecursiveActionTest extends
1055       * there are more tasks than threads
1056       */
1057      public void testGetSurplusQueuedTaskCount() {
1058 <        RecursiveAction a = new RecursiveAction() {
1059 <                public void compute() {
1060 <                    FibAction h = new FibAction(7);
1061 <                    h.fork();
1062 <                    FibAction g = new FibAction(9);
1063 <                    g.fork();
1064 <                    FibAction f = new FibAction(8);
1065 <                    f.fork();
1066 <                    threadAssertTrue(getSurplusQueuedTaskCount() > 0);
1067 <                    helpQuiesce();
1068 <                }
1069 <            };
1070 <        singletonPool.invoke(a);
1058 >        RecursiveAction a = new CheckedRecursiveAction() {
1059 >            protected void realCompute() {
1060 >                FibAction h = new FibAction(7);
1061 >                assertSame(h, h.fork());
1062 >                FibAction g = new FibAction(9);
1063 >                assertSame(g, g.fork());
1064 >                FibAction f = new FibAction(8);
1065 >                assertSame(f, f.fork());
1066 >                assertTrue(getSurplusQueuedTaskCount() > 0);
1067 >                helpQuiesce();
1068 >                assertEquals(0, getSurplusQueuedTaskCount());
1069 >                checkCompletedNormally(f);
1070 >                checkCompletedNormally(g);
1071 >                checkCompletedNormally(h);
1072 >            }};
1073 >        testInvokeOnPool(singletonPool(), a);
1074      }
1075  
1076      /**
1077       * peekNextLocalTask returns most recent unexecuted task.
1078       */
1079      public void testPeekNextLocalTask() {
1080 <        RecursiveAction a = new RecursiveAction() {
1081 <                public void compute() {
1082 <                    FibAction g = new FibAction(9);
1083 <                    g.fork();
1084 <                    FibAction f = new FibAction(8);
1085 <                    f.fork();
1086 <                    threadAssertTrue(peekNextLocalTask() == f);
1087 <                    f.join();
1088 <                    threadAssertTrue(f.isDone());
1089 <                    helpQuiesce();
1090 <                }
1091 <            };
1092 <        singletonPool.invoke(a);
1080 >        RecursiveAction a = new CheckedRecursiveAction() {
1081 >            protected void realCompute() {
1082 >                FibAction g = new FibAction(9);
1083 >                assertSame(g, g.fork());
1084 >                FibAction f = new FibAction(8);
1085 >                assertSame(f, f.fork());
1086 >                assertSame(f, peekNextLocalTask());
1087 >                assertNull(f.join());
1088 >                checkCompletedNormally(f);
1089 >                helpQuiesce();
1090 >                checkCompletedNormally(f);
1091 >                checkCompletedNormally(g);
1092 >            }};
1093 >        testInvokeOnPool(singletonPool(), a);
1094      }
1095  
1096      /**
# Line 911 | Line 1098 | public class RecursiveActionTest extends
1098       * without executing it
1099       */
1100      public void testPollNextLocalTask() {
1101 <        RecursiveAction a = new RecursiveAction() {
1102 <                public void compute() {
1103 <                    FibAction g = new FibAction(9);
1104 <                    g.fork();
1105 <                    FibAction f = new FibAction(8);
1106 <                    f.fork();
1107 <                    threadAssertTrue(pollNextLocalTask() == f);
1108 <                    helpQuiesce();
1109 <                    threadAssertFalse(f.isDone());
1110 <                }
1111 <            };
1112 <        singletonPool.invoke(a);
1101 >        RecursiveAction a = new CheckedRecursiveAction() {
1102 >            protected void realCompute() {
1103 >                FibAction g = new FibAction(9);
1104 >                assertSame(g, g.fork());
1105 >                FibAction f = new FibAction(8);
1106 >                assertSame(f, f.fork());
1107 >                assertSame(f, pollNextLocalTask());
1108 >                helpQuiesce();
1109 >                checkNotDone(f);
1110 >                checkCompletedNormally(g);
1111 >            }};
1112 >        testInvokeOnPool(singletonPool(), a);
1113      }
1114  
1115      /**
1116 <     * pollTask returns an unexecuted task
930 <     * without executing it
1116 >     * pollTask returns an unexecuted task without executing it
1117       */
1118      public void testPollTask() {
1119 <        RecursiveAction a = new RecursiveAction() {
1120 <                public void compute() {
1121 <                    FibAction g = new FibAction(9);
1122 <                    g.fork();
1123 <                    FibAction f = new FibAction(8);
1124 <                    f.fork();
1125 <                    threadAssertTrue(pollTask() == f);
1126 <                    helpQuiesce();
1127 <                    threadAssertFalse(f.isDone());
1128 <                    threadAssertTrue(g.isDone());
1129 <                }
1130 <            };
945 <        singletonPool.invoke(a);
1119 >        RecursiveAction a = new CheckedRecursiveAction() {
1120 >            protected void realCompute() {
1121 >                FibAction g = new FibAction(9);
1122 >                assertSame(g, g.fork());
1123 >                FibAction f = new FibAction(8);
1124 >                assertSame(f, f.fork());
1125 >                assertSame(f, pollTask());
1126 >                helpQuiesce();
1127 >                checkNotDone(f);
1128 >                checkCompletedNormally(g);
1129 >            }};
1130 >        testInvokeOnPool(singletonPool(), a);
1131      }
1132  
1133      /**
1134       * peekNextLocalTask returns least recent unexecuted task in async mode
1135       */
1136      public void testPeekNextLocalTaskAsync() {
1137 <        RecursiveAction a = new RecursiveAction() {
1138 <                public void compute() {
1139 <                    FibAction g = new FibAction(9);
1140 <                    g.fork();
1141 <                    FibAction f = new FibAction(8);
1142 <                    f.fork();
1143 <                    threadAssertTrue(peekNextLocalTask() == g);
1144 <                    f.join();
1145 <                    helpQuiesce();
1146 <                    threadAssertTrue(f.isDone());
1147 <                }
1148 <            };
1149 <        asyncSingletonPool.invoke(a);
1137 >        RecursiveAction a = new CheckedRecursiveAction() {
1138 >            protected void realCompute() {
1139 >                FibAction g = new FibAction(9);
1140 >                assertSame(g, g.fork());
1141 >                FibAction f = new FibAction(8);
1142 >                assertSame(f, f.fork());
1143 >                assertSame(g, peekNextLocalTask());
1144 >                assertNull(f.join());
1145 >                helpQuiesce();
1146 >                checkCompletedNormally(f);
1147 >                checkCompletedNormally(g);
1148 >            }};
1149 >        testInvokeOnPool(asyncSingletonPool(), a);
1150      }
1151  
1152      /**
1153 <     * pollNextLocalTask returns least recent unexecuted task
1154 <     * without executing it, in async mode
1153 >     * pollNextLocalTask returns least recent unexecuted task without
1154 >     * executing it, in async mode
1155       */
1156      public void testPollNextLocalTaskAsync() {
1157 <        RecursiveAction a = new RecursiveAction() {
1158 <                public void compute() {
1159 <                    FibAction g = new FibAction(9);
1160 <                    g.fork();
1161 <                    FibAction f = new FibAction(8);
1162 <                    f.fork();
1163 <                    threadAssertTrue(pollNextLocalTask() == g);
1164 <                    helpQuiesce();
1165 <                    threadAssertTrue(f.isDone());
1166 <                    threadAssertFalse(g.isDone());
1167 <                }
1168 <            };
984 <        asyncSingletonPool.invoke(a);
1157 >        RecursiveAction a = new CheckedRecursiveAction() {
1158 >            protected void realCompute() {
1159 >                FibAction g = new FibAction(9);
1160 >                assertSame(g, g.fork());
1161 >                FibAction f = new FibAction(8);
1162 >                assertSame(f, f.fork());
1163 >                assertSame(g, pollNextLocalTask());
1164 >                helpQuiesce();
1165 >                checkCompletedNormally(f);
1166 >                checkNotDone(g);
1167 >            }};
1168 >        testInvokeOnPool(asyncSingletonPool(), a);
1169      }
1170  
1171      /**
1172 <     * pollTask returns an unexecuted task
1173 <     * without executing it, in async mode
1172 >     * pollTask returns an unexecuted task without executing it, in
1173 >     * async mode
1174       */
1175      public void testPollTaskAsync() {
1176 <        RecursiveAction a = new RecursiveAction() {
1177 <                public void compute() {
1178 <                    FibAction g = new FibAction(9);
1179 <                    g.fork();
1180 <                    FibAction f = new FibAction(8);
1181 <                    f.fork();
1182 <                    threadAssertTrue(pollTask() == g);
1183 <                    helpQuiesce();
1184 <                    threadAssertTrue(f.isDone());
1185 <                    threadAssertFalse(g.isDone());
1186 <                }
1187 <            };
1188 <        asyncSingletonPool.invoke(a);
1176 >        RecursiveAction a = new CheckedRecursiveAction() {
1177 >            protected void realCompute() {
1178 >                FibAction g = new FibAction(9);
1179 >                assertSame(g, g.fork());
1180 >                FibAction f = new FibAction(8);
1181 >                assertSame(f, f.fork());
1182 >                assertSame(g, pollTask());
1183 >                helpQuiesce();
1184 >                checkCompletedNormally(f);
1185 >                checkNotDone(g);
1186 >            }};
1187 >        testInvokeOnPool(asyncSingletonPool(), a);
1188 >    }
1189 >
1190 >    /** Demo from RecursiveAction javadoc */
1191 >    static class SortTask extends RecursiveAction {
1192 >        final long[] array; final int lo, hi;
1193 >        SortTask(long[] array, int lo, int hi) {
1194 >            this.array = array; this.lo = lo; this.hi = hi;
1195 >        }
1196 >        SortTask(long[] array) { this(array, 0, array.length); }
1197 >        protected void compute() {
1198 >            if (hi - lo < THRESHOLD)
1199 >                sortSequentially(lo, hi);
1200 >            else {
1201 >                int mid = (lo + hi) >>> 1;
1202 >                invokeAll(new SortTask(array, lo, mid),
1203 >                          new SortTask(array, mid, hi));
1204 >                merge(lo, mid, hi);
1205 >            }
1206 >        }
1207 >        // implementation details follow:
1208 >        static final int THRESHOLD = 100;
1209 >        void sortSequentially(int lo, int hi) {
1210 >            Arrays.sort(array, lo, hi);
1211 >        }
1212 >        void merge(int lo, int mid, int hi) {
1213 >            long[] buf = Arrays.copyOfRange(array, lo, mid);
1214 >            for (int i = 0, j = lo, k = mid; i < buf.length; j++)
1215 >                array[j] = (k == hi || buf[i] < array[k]) ?
1216 >                    buf[i++] : array[k++];
1217 >        }
1218      }
1219  
1220 +    /**
1221 +     * SortTask demo works as advertised
1222 +     */
1223 +    public void testSortTaskDemo() {
1224 +        ThreadLocalRandom rnd = ThreadLocalRandom.current();
1225 +        long[] array = new long[1007];
1226 +        for (int i = 0; i < array.length; i++)
1227 +            array[i] = rnd.nextLong();
1228 +        long[] arrayClone = array.clone();
1229 +        testInvokeOnPool(mainPool(), new SortTask(array));
1230 +        Arrays.sort(arrayClone);
1231 +        assertTrue(Arrays.equals(array, arrayClone));
1232 +    }
1233   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines