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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines