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

Comparing jsr166/src/test/tck/RecursiveActionTest.java (file contents):
Revision 1.2 by jsr166, Fri Jul 31 23:37:31 2009 UTC vs.
Revision 1.43 by jsr166, Sun Feb 22 19:16:38 2015 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines