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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines