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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines