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.13 by jsr166, Sat Sep 11 07:31:52 2010 UTC vs.
Revision 1.42 by jsr166, Sun Feb 22 04:52:47 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 + import java.util.concurrent.TimeUnit;
21 +
22 + import junit.framework.Test;
23 + import junit.framework.TestSuite;
24  
25   public class RecursiveActionTest extends JSR166TestCase {
26  
# Line 18 | Line 32 | public class RecursiveActionTest extends
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 =
38 <        new ForkJoinPool(1, ForkJoinPool.defaultForkJoinWorkerThreadFactory,
39 <                         null, 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 <    static final class FJException extends RuntimeException {
44 <        FJException() { super(); }
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 >    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 70 | Line 213 | public class RecursiveActionTest extends
213       * completed tasks. getRawResult of a RecursiveAction returns null;
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());
79 <                threadAssertFalse(f.isCancelled());
80 <                threadAssertFalse(f.isCompletedAbnormally());
81 <                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 89 | 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());
98 <                threadAssertFalse(f.isCancelled());
99 <                threadAssertFalse(f.isCompletedAbnormally());
100 <                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());
116 <                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());
286 <                } catch (Exception ex) {
287 <                    unexpectedException(ex);
281 >                    f.join();
282 >                    shouldThrow();
283 >                } catch (CancellationException success) {
284 >                    Thread.interrupted();
285 >                    checkCancelled(f);
286 >                }
287 >
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 >                    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 of a forked task returns when task completes
335 >     * join/quietlyJoin of a forked task when not in ForkJoinPool
336 >     * succeeds in the presence of interrupts
337       */
338 <    public void testForkTimedGet() {
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 >                    f.join();
382 >                    shouldThrow();
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 <                    FibAction f = new FibAction(8);
393 <                    f.fork();
394 <                    f.get(5L, TimeUnit.SECONDS);
395 <                    threadAssertTrue(f.result == 21);
396 <                    threadAssertTrue(f.isDone());
152 <                } catch (Exception ex) {
153 <                    unexpectedException(ex);
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 >     * get of a forked task returns when task completes
439 >     */
440 >    public void testForkGet() {
441 >        RecursiveAction a = new CheckedRecursiveAction() {
442 >            protected void realCompute() throws Exception {
443 >                FibAction f = new FibAction(8);
444 >                assertSame(f, f.fork());
445 >                assertNull(f.get());
446 >                assertEquals(21, f.result);
447 >                checkCompletedNormally(f);
448 >            }};
449 >        testInvokeOnPool(mainPool(), a);
450 >    }
451 >
452 >    /**
453 >     * timed get of a forked task returns when task completes
454 >     */
455 >    public void testForkTimedGet() {
456 >        RecursiveAction a = new CheckedRecursiveAction() {
457 >            protected void realCompute() throws Exception {
458 >                FibAction f = new FibAction(8);
459 >                assertSame(f, f.fork());
460 >                assertNull(f.get(5L, SECONDS));
461 >                assertEquals(21, f.result);
462 >                checkCompletedNormally(f);
463 >            }};
464 >        testInvokeOnPool(mainPool(), a);
465      }
466  
467      /**
468       * timed get with null time unit throws NPE
469       */
470      public void testForkTimedGetNPE() {
471 <        RecursiveAction a = new RecursiveAction() {
472 <            public void compute() {
471 >        RecursiveAction a = new CheckedRecursiveAction() {
472 >            protected void realCompute() throws Exception {
473 >                FibAction f = new FibAction(8);
474 >                assertSame(f, f.fork());
475                  try {
166                    FibAction f = new FibAction(8);
167                    f.fork();
476                      f.get(5L, null);
477                      shouldThrow();
478 <                } catch (NullPointerException success) {
171 <                } catch (Exception ex) {
172 <                    unexpectedException(ex);
173 <                }
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 RecursiveAction() {
488 <            public void compute() {
487 >        RecursiveAction a = new CheckedRecursiveAction() {
488 >            protected void realCompute() {
489                  FibAction f = new FibAction(8);
490 <                f.fork();
490 >                assertSame(f, f.fork());
491                  f.quietlyJoin();
492 <                threadAssertTrue(f.result == 21);
493 <                threadAssertTrue(f.isDone());
492 >                assertEquals(21, f.result);
493 >                checkCompletedNormally(f);
494              }};
495 <        mainPool.invoke(a);
495 >        testInvokeOnPool(mainPool(), a);
496      }
497  
193
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 >                while (!f.isDone()) // wait out race
509 >                    ;
510 >                assertEquals(21, f.result);
511 >                assertEquals(0, getQueuedTaskCount());
512 >                checkCompletedNormally(f);
513              }};
514 <        mainPool.invoke(a);
514 >        testInvokeOnPool(mainPool(), a);
515      }
516  
211
517      /**
518       * invoke task throws exception when task completes abnormally
519       */
520      public void testAbnormalInvoke() {
521 <        RecursiveAction a = new RecursiveAction() {
522 <            public void compute() {
521 >        RecursiveAction a = new CheckedRecursiveAction() {
522 >            protected void realCompute() {
523 >                FailingFibAction f = new FailingFibAction(8);
524                  try {
219                    FailingFibAction f = new FailingFibAction(8);
525                      f.invoke();
526                      shouldThrow();
527                  } catch (FJException success) {
528 +                    checkCompletedAbnormally(f, success);
529                  }
530              }};
531 <        mainPool.invoke(a);
531 >        testInvokeOnPool(mainPool(), a);
532      }
533  
534      /**
535       * quietlyInvoke task returns when task completes abnormally
536       */
537      public void testAbnormalQuietlyInvoke() {
538 <        RecursiveAction a = new RecursiveAction() {
539 <            public void compute() {
538 >        RecursiveAction a = new CheckedRecursiveAction() {
539 >            protected void realCompute() {
540                  FailingFibAction f = new FailingFibAction(8);
541                  f.quietlyInvoke();
542 <                threadAssertTrue(f.isDone());
542 >                assertTrue(f.getException() instanceof FJException);
543 >                checkCompletedAbnormally(f, f.getException());
544              }};
545 <        mainPool.invoke(a);
545 >        testInvokeOnPool(mainPool(), a);
546      }
547  
548      /**
549       * join of a forked task throws exception when task completes abnormally
550       */
551      public void testAbnormalForkJoin() {
552 <        RecursiveAction a = new RecursiveAction() {
553 <            public void compute() {
552 >        RecursiveAction a = new CheckedRecursiveAction() {
553 >            protected void realCompute() {
554 >                FailingFibAction f = new FailingFibAction(8);
555 >                assertSame(f, f.fork());
556                  try {
248                    FailingFibAction f = new FailingFibAction(8);
249                    f.fork();
557                      f.join();
558                      shouldThrow();
559                  } catch (FJException success) {
560 +                    checkCompletedAbnormally(f, success);
561                  }
562              }};
563 <        mainPool.invoke(a);
563 >        testInvokeOnPool(mainPool(), a);
564      }
565  
566      /**
567       * get of a forked task throws exception when task completes abnormally
568       */
569      public void testAbnormalForkGet() {
570 <        RecursiveAction a = new RecursiveAction() {
571 <            public void compute() {
570 >        RecursiveAction a = new CheckedRecursiveAction() {
571 >            protected void realCompute() throws Exception {
572 >                FailingFibAction f = new FailingFibAction(8);
573 >                assertSame(f, f.fork());
574                  try {
265                    FailingFibAction f = new FailingFibAction(8);
266                    f.fork();
575                      f.get();
576                      shouldThrow();
577                  } catch (ExecutionException success) {
578 <                } catch (Exception ex) {
579 <                    unexpectedException(ex);
578 >                    Throwable cause = success.getCause();
579 >                    assertTrue(cause instanceof FJException);
580 >                    checkCompletedAbnormally(f, cause);
581                  }
582              }};
583 <        mainPool.invoke(a);
583 >        testInvokeOnPool(mainPool(), a);
584      }
585  
586      /**
587       * timed get of a forked task throws exception when task completes abnormally
588       */
589      public void testAbnormalForkTimedGet() {
590 <        RecursiveAction a = new RecursiveAction() {
591 <            public void compute() {
590 >        RecursiveAction a = new CheckedRecursiveAction() {
591 >            protected void realCompute() throws Exception {
592 >                FailingFibAction f = new FailingFibAction(8);
593 >                assertSame(f, f.fork());
594                  try {
595 <                    FailingFibAction f = new FailingFibAction(8);
285 <                    f.fork();
286 <                    f.get(5L, TimeUnit.SECONDS);
595 >                    f.get(5L, SECONDS);
596                      shouldThrow();
597                  } catch (ExecutionException success) {
598 <                } catch (Exception ex) {
599 <                    unexpectedException(ex);
598 >                    Throwable cause = success.getCause();
599 >                    assertTrue(cause instanceof FJException);
600 >                    checkCompletedAbnormally(f, cause);
601                  }
602              }};
603 <        mainPool.invoke(a);
603 >        testInvokeOnPool(mainPool(), a);
604      }
605  
606      /**
607       * quietlyJoin of a forked task returns when task completes abnormally
608       */
609      public void testAbnormalForkQuietlyJoin() {
610 <        RecursiveAction a = new RecursiveAction() {
611 <            public void compute() {
610 >        RecursiveAction a = new CheckedRecursiveAction() {
611 >            protected void realCompute() {
612                  FailingFibAction f = new FailingFibAction(8);
613 <                f.fork();
613 >                assertSame(f, f.fork());
614                  f.quietlyJoin();
615 <                threadAssertTrue(f.isDone());
616 <                threadAssertTrue(f.isCompletedAbnormally());
307 <                threadAssertTrue(f.getException() instanceof FJException);
615 >                assertTrue(f.getException() instanceof FJException);
616 >                checkCompletedAbnormally(f, f.getException());
617              }};
618 <        mainPool.invoke(a);
618 >        testInvokeOnPool(mainPool(), a);
619      }
620  
621      /**
622       * invoke task throws exception when task cancelled
623       */
624      public void testCancelledInvoke() {
625 <        RecursiveAction a = new RecursiveAction() {
626 <            public void compute() {
625 >        RecursiveAction a = new CheckedRecursiveAction() {
626 >            protected void realCompute() {
627 >                FibAction f = new FibAction(8);
628 >                assertTrue(f.cancel(true));
629                  try {
319                    FibAction f = new FibAction(8);
320                    f.cancel(true);
630                      f.invoke();
631                      shouldThrow();
632                  } catch (CancellationException success) {
633 +                    checkCancelled(f);
634                  }
635              }};
636 <        mainPool.invoke(a);
636 >        testInvokeOnPool(mainPool(), a);
637      }
638  
639      /**
640       * join of a forked task throws exception when task cancelled
641       */
642      public void testCancelledForkJoin() {
643 <        RecursiveAction a = new RecursiveAction() {
644 <            public void compute() {
643 >        RecursiveAction a = new CheckedRecursiveAction() {
644 >            protected void realCompute() {
645 >                FibAction f = new FibAction(8);
646 >                assertTrue(f.cancel(true));
647 >                assertSame(f, f.fork());
648                  try {
336                    FibAction f = new FibAction(8);
337                    f.cancel(true);
338                    f.fork();
649                      f.join();
650                      shouldThrow();
651                  } catch (CancellationException success) {
652 +                    checkCancelled(f);
653                  }
654              }};
655 <        mainPool.invoke(a);
655 >        testInvokeOnPool(mainPool(), a);
656      }
657  
658      /**
659       * get of a forked task throws exception when task cancelled
660       */
661      public void testCancelledForkGet() {
662 <        RecursiveAction a = new RecursiveAction() {
663 <            public void compute() {
662 >        RecursiveAction a = new CheckedRecursiveAction() {
663 >            protected void realCompute() throws Exception {
664 >                FibAction f = new FibAction(8);
665 >                assertTrue(f.cancel(true));
666 >                assertSame(f, f.fork());
667                  try {
354                    FibAction f = new FibAction(8);
355                    f.cancel(true);
356                    f.fork();
668                      f.get();
669                      shouldThrow();
670                  } catch (CancellationException success) {
671 <                } catch (Exception ex) {
361 <                    unexpectedException(ex);
671 >                    checkCancelled(f);
672                  }
673              }};
674 <        mainPool.invoke(a);
674 >        testInvokeOnPool(mainPool(), a);
675      }
676  
677      /**
678       * timed get of a forked task throws exception when task cancelled
679       */
680      public void testCancelledForkTimedGet() {
681 <        RecursiveAction a = new RecursiveAction() {
682 <            public void compute() {
681 >        RecursiveAction a = new CheckedRecursiveAction() {
682 >            protected void realCompute() throws Exception {
683 >                FibAction f = new FibAction(8);
684 >                assertTrue(f.cancel(true));
685 >                assertSame(f, f.fork());
686                  try {
687 <                    FibAction f = new FibAction(8);
375 <                    f.cancel(true);
376 <                    f.fork();
377 <                    f.get(5L, TimeUnit.SECONDS);
687 >                    f.get(5L, SECONDS);
688                      shouldThrow();
689                  } catch (CancellationException success) {
690 <                } catch (Exception ex) {
381 <                    unexpectedException(ex);
690 >                    checkCancelled(f);
691                  }
692              }};
693 <        mainPool.invoke(a);
693 >        testInvokeOnPool(mainPool(), a);
694      }
695  
696      /**
697       * quietlyJoin of a forked task returns when task cancelled
698       */
699      public void testCancelledForkQuietlyJoin() {
700 <        RecursiveAction a = new RecursiveAction() {
701 <            public void compute() {
700 >        RecursiveAction a = new CheckedRecursiveAction() {
701 >            protected void realCompute() {
702                  FibAction f = new FibAction(8);
703 <                f.cancel(true);
704 <                f.fork();
703 >                assertTrue(f.cancel(true));
704 >                assertSame(f, f.fork());
705                  f.quietlyJoin();
706 <                threadAssertTrue(f.isDone());
398 <                threadAssertTrue(f.isCompletedAbnormally());
399 <                threadAssertTrue(f.getException() instanceof CancellationException);
706 >                checkCancelled(f);
707              }};
708 <        mainPool.invoke(a);
708 >        testInvokeOnPool(mainPool(), a);
709      }
710  
711      /**
712       * getPool of executing task returns its pool
713       */
714      public void testGetPool() {
715 <        RecursiveAction a = new RecursiveAction() {
716 <            public void compute() {
717 <                threadAssertTrue(getPool() == mainPool);
715 >        final ForkJoinPool mainPool = mainPool();
716 >        RecursiveAction a = new CheckedRecursiveAction() {
717 >            protected void realCompute() {
718 >                assertSame(mainPool, getPool());
719              }};
720 <        mainPool.invoke(a);
720 >        testInvokeOnPool(mainPool, a);
721      }
722  
723      /**
724       * getPool of non-FJ task returns null
725       */
726      public void testGetPool2() {
727 <        RecursiveAction a = new RecursiveAction() {
728 <            public void compute() {
729 <                threadAssertTrue(getPool() == null);
727 >        RecursiveAction a = new CheckedRecursiveAction() {
728 >            protected void realCompute() {
729 >                assertNull(getPool());
730              }};
731 <        a.invoke();
731 >        assertNull(a.invoke());
732      }
733  
734      /**
735       * inForkJoinPool of executing task returns true
736       */
737      public void testInForkJoinPool() {
738 <        RecursiveAction a = new RecursiveAction() {
739 <            public void compute() {
740 <                threadAssertTrue(inForkJoinPool());
738 >        RecursiveAction a = new CheckedRecursiveAction() {
739 >            protected void realCompute() {
740 >                assertTrue(inForkJoinPool());
741              }};
742 <        mainPool.invoke(a);
742 >        testInvokeOnPool(mainPool(), a);
743      }
744  
745      /**
746       * inForkJoinPool of non-FJ task returns false
747       */
748      public void testInForkJoinPool2() {
749 <        RecursiveAction a = new RecursiveAction() {
750 <            public void compute() {
751 <                threadAssertTrue(!inForkJoinPool());
749 >        RecursiveAction a = new CheckedRecursiveAction() {
750 >            protected void realCompute() {
751 >                assertFalse(inForkJoinPool());
752              }};
753 <        a.invoke();
753 >        assertNull(a.invoke());
754      }
755  
756      /**
757       * getPool of current thread in pool returns its pool
758       */
759      public void testWorkerGetPool() {
760 <        RecursiveAction a = new RecursiveAction() {
761 <            public void compute() {
760 >        final ForkJoinPool mainPool = mainPool();
761 >        RecursiveAction a = new CheckedRecursiveAction() {
762 >            protected void realCompute() {
763                  ForkJoinWorkerThread w =
764 <                    (ForkJoinWorkerThread)(Thread.currentThread());
765 <                threadAssertTrue(w.getPool() == mainPool);
764 >                    (ForkJoinWorkerThread) Thread.currentThread();
765 >                assertSame(mainPool, w.getPool());
766              }};
767 <        mainPool.invoke(a);
767 >        testInvokeOnPool(mainPool, a);
768      }
769  
770      /**
771       * getPoolIndex of current thread in pool returns 0 <= value < poolSize
772       */
773      public void testWorkerGetPoolIndex() {
774 <        RecursiveAction a = new RecursiveAction() {
775 <            public void compute() {
774 >        final ForkJoinPool mainPool = mainPool();
775 >        RecursiveAction a = new CheckedRecursiveAction() {
776 >            protected void realCompute() {
777                  ForkJoinWorkerThread w =
778 <                    (ForkJoinWorkerThread)(Thread.currentThread());
779 <                int idx = w.getPoolIndex();
780 <                threadAssertTrue(idx >= 0);
781 <                threadAssertTrue(idx < mainPool.getPoolSize());
778 >                    (ForkJoinWorkerThread) Thread.currentThread();
779 >                assertTrue(w.getPoolIndex() >= 0);
780 >                // pool size can shrink after assigning index, so cannot check
781 >                // assertTrue(w.getPoolIndex() < mainPool.getPoolSize());
782              }};
783 <        mainPool.invoke(a);
783 >        testInvokeOnPool(mainPool, a);
784      }
785  
476
786      /**
787       * setRawResult(null) succeeds
788       */
789      public void testSetRawResult() {
790 <        RecursiveAction a = new RecursiveAction() {
791 <            public void compute() {
790 >        RecursiveAction a = new CheckedRecursiveAction() {
791 >            protected void realCompute() {
792                  setRawResult(null);
793 +                assertNull(getRawResult());
794              }};
795 <        a.invoke();
795 >        assertNull(a.invoke());
796      }
797  
798      /**
799 <     * A reinitialized task may be re-invoked
799 >     * A reinitialized normally completed task may be re-invoked
800       */
801      public void testReinitialize() {
802 <        RecursiveAction a = new RecursiveAction() {
803 <            public void compute() {
802 >        RecursiveAction a = new CheckedRecursiveAction() {
803 >            protected void realCompute() {
804                  FibAction f = new FibAction(8);
805 <                f.invoke();
806 <                threadAssertTrue(f.result == 21);
807 <                threadAssertTrue(f.isDone());
808 <                threadAssertFalse(f.isCancelled());
809 <                threadAssertFalse(f.isCompletedAbnormally());
810 <                f.reinitialize();
811 <                f.invoke();
812 <                threadAssertTrue(f.result == 21);
805 >                checkNotDone(f);
806 >
807 >                for (int i = 0; i < 3; i++) {
808 >                    assertNull(f.invoke());
809 >                    assertEquals(21, f.result);
810 >                    checkCompletedNormally(f);
811 >                    f.reinitialize();
812 >                    checkNotDone(f);
813 >                }
814              }};
815 <        mainPool.invoke(a);
815 >        testInvokeOnPool(mainPool(), a);
816 >    }
817 >
818 >    /**
819 >     * A reinitialized abnormally completed task may be re-invoked
820 >     */
821 >    public void testReinitializeAbnormal() {
822 >        RecursiveAction a = new CheckedRecursiveAction() {
823 >            protected void realCompute() {
824 >                FailingFibAction f = new FailingFibAction(8);
825 >                checkNotDone(f);
826 >
827 >                for (int i = 0; i < 3; i++) {
828 >                    try {
829 >                        f.invoke();
830 >                        shouldThrow();
831 >                    } catch (FJException success) {
832 >                        checkCompletedAbnormally(f, success);
833 >                    }
834 >                    f.reinitialize();
835 >                    checkNotDone(f);
836 >                }
837 >            }};
838 >        testInvokeOnPool(mainPool(), a);
839      }
840  
841      /**
842       * invoke task throws exception after invoking completeExceptionally
843       */
844      public void testCompleteExceptionally() {
845 <        RecursiveAction a = new RecursiveAction() {
846 <            public void compute() {
845 >        RecursiveAction a = new CheckedRecursiveAction() {
846 >            protected void realCompute() {
847 >                FibAction f = new FibAction(8);
848 >                f.completeExceptionally(new FJException());
849                  try {
514                    FibAction f = new FibAction(8);
515                    f.completeExceptionally(new FJException());
850                      f.invoke();
851                      shouldThrow();
852                  } catch (FJException success) {
853 +                    checkCompletedAbnormally(f, success);
854                  }
855              }};
856 <        mainPool.invoke(a);
856 >        testInvokeOnPool(mainPool(), a);
857      }
858  
859      /**
860       * invoke task suppresses execution invoking complete
861       */
862      public void testComplete() {
863 <        RecursiveAction a = new RecursiveAction() {
864 <            public void compute() {
863 >        RecursiveAction a = new CheckedRecursiveAction() {
864 >            protected void realCompute() {
865                  FibAction f = new FibAction(8);
866                  f.complete(null);
867 <                f.invoke();
868 <                threadAssertTrue(f.isDone());
869 <                threadAssertTrue(f.result == 0);
867 >                assertNull(f.invoke());
868 >                assertEquals(0, f.result);
869 >                checkCompletedNormally(f);
870              }};
871 <        mainPool.invoke(a);
871 >        testInvokeOnPool(mainPool(), a);
872      }
873  
874      /**
875       * invokeAll(t1, t2) invokes all task arguments
876       */
877      public void testInvokeAll2() {
878 <        RecursiveAction a = new RecursiveAction() {
879 <            public void compute() {
878 >        RecursiveAction a = new CheckedRecursiveAction() {
879 >            protected void realCompute() {
880                  FibAction f = new FibAction(8);
881                  FibAction g = new FibAction(9);
882                  invokeAll(f, g);
883 <                threadAssertTrue(f.isDone());
884 <                threadAssertTrue(f.result == 21);
885 <                threadAssertTrue(g.isDone());
886 <                threadAssertTrue(g.result == 34);
883 >                checkCompletedNormally(f);
884 >                assertEquals(21, f.result);
885 >                checkCompletedNormally(g);
886 >                assertEquals(34, g.result);
887              }};
888 <        mainPool.invoke(a);
888 >        testInvokeOnPool(mainPool(), a);
889      }
890  
891      /**
892       * invokeAll(tasks) with 1 argument invokes task
893       */
894      public void testInvokeAll1() {
895 <        RecursiveAction a = new RecursiveAction() {
896 <            public void compute() {
895 >        RecursiveAction a = new CheckedRecursiveAction() {
896 >            protected void realCompute() {
897                  FibAction f = new FibAction(8);
898                  invokeAll(f);
899 <                threadAssertTrue(f.isDone());
900 <                threadAssertTrue(f.result == 21);
899 >                checkCompletedNormally(f);
900 >                assertEquals(21, f.result);
901              }};
902 <        mainPool.invoke(a);
902 >        testInvokeOnPool(mainPool(), a);
903      }
904  
905      /**
906       * invokeAll(tasks) with > 2 argument invokes tasks
907       */
908      public void testInvokeAll3() {
909 <        RecursiveAction a = new RecursiveAction() {
910 <            public void compute() {
909 >        RecursiveAction a = new CheckedRecursiveAction() {
910 >            protected void realCompute() {
911                  FibAction f = new FibAction(8);
912                  FibAction g = new FibAction(9);
913                  FibAction h = new FibAction(7);
914                  invokeAll(f, g, h);
915 <                threadAssertTrue(f.isDone());
916 <                threadAssertTrue(f.result == 21);
917 <                threadAssertTrue(g.isDone());
918 <                threadAssertTrue(g.result == 34);
919 <                threadAssertTrue(h.isDone());
920 <                threadAssertTrue(h.result == 13);
915 >                assertTrue(f.isDone());
916 >                assertTrue(g.isDone());
917 >                assertTrue(h.isDone());
918 >                checkCompletedNormally(f);
919 >                assertEquals(21, f.result);
920 >                checkCompletedNormally(g);
921 >                assertEquals(34, g.result);
922 >                checkCompletedNormally(g);
923 >                assertEquals(13, h.result);
924              }};
925 <        mainPool.invoke(a);
925 >        testInvokeOnPool(mainPool(), a);
926      }
927  
928      /**
929       * invokeAll(collection) invokes all tasks in the collection
930       */
931      public void testInvokeAllCollection() {
932 <        RecursiveAction a = new RecursiveAction() {
933 <            public void compute() {
932 >        RecursiveAction a = new CheckedRecursiveAction() {
933 >            protected void realCompute() {
934                  FibAction f = new FibAction(8);
935                  FibAction g = new FibAction(9);
936                  FibAction h = new FibAction(7);
# Line 601 | Line 939 | public class RecursiveActionTest extends
939                  set.add(g);
940                  set.add(h);
941                  invokeAll(set);
942 <                threadAssertTrue(f.isDone());
943 <                threadAssertTrue(f.result == 21);
944 <                threadAssertTrue(g.isDone());
945 <                threadAssertTrue(g.result == 34);
946 <                threadAssertTrue(h.isDone());
947 <                threadAssertTrue(h.result == 13);
942 >                assertTrue(f.isDone());
943 >                assertTrue(g.isDone());
944 >                assertTrue(h.isDone());
945 >                checkCompletedNormally(f);
946 >                assertEquals(21, f.result);
947 >                checkCompletedNormally(g);
948 >                assertEquals(34, g.result);
949 >                checkCompletedNormally(g);
950 >                assertEquals(13, h.result);
951              }};
952 <        mainPool.invoke(a);
952 >        testInvokeOnPool(mainPool(), a);
953      }
954  
614
955      /**
956       * invokeAll(tasks) with any null task throws NPE
957       */
958      public void testInvokeAllNPE() {
959 <        RecursiveAction a = new RecursiveAction() {
960 <            public void compute() {
959 >        RecursiveAction a = new CheckedRecursiveAction() {
960 >            protected void realCompute() {
961 >                FibAction f = new FibAction(8);
962 >                FibAction g = new FibAction(9);
963 >                FibAction h = null;
964                  try {
622                    FibAction f = new FibAction(8);
623                    FibAction g = new FibAction(9);
624                    FibAction h = null;
965                      invokeAll(f, g, h);
966                      shouldThrow();
967 <                } catch (NullPointerException success) {
628 <                }
967 >                } catch (NullPointerException success) {}
968              }};
969 <        mainPool.invoke(a);
969 >        testInvokeOnPool(mainPool(), a);
970      }
971  
972      /**
973       * invokeAll(t1, t2) throw exception if any task does
974       */
975      public void testAbnormalInvokeAll2() {
976 <        RecursiveAction a = new RecursiveAction() {
977 <            public void compute() {
976 >        RecursiveAction a = new CheckedRecursiveAction() {
977 >            protected void realCompute() {
978 >                FibAction f = new FibAction(8);
979 >                FailingFibAction g = new FailingFibAction(9);
980                  try {
640                    FibAction f = new FibAction(8);
641                    FailingFibAction g = new FailingFibAction(9);
981                      invokeAll(f, g);
982                      shouldThrow();
983                  } catch (FJException success) {
984 +                    checkCompletedAbnormally(g, success);
985                  }
986              }};
987 <        mainPool.invoke(a);
987 >        testInvokeOnPool(mainPool(), a);
988      }
989  
990      /**
991       * invokeAll(tasks) with 1 argument throws exception if task does
992       */
993      public void testAbnormalInvokeAll1() {
994 <        RecursiveAction a = new RecursiveAction() {
995 <            public void compute() {
994 >        RecursiveAction a = new CheckedRecursiveAction() {
995 >            protected void realCompute() {
996 >                FailingFibAction g = new FailingFibAction(9);
997                  try {
657                    FailingFibAction g = new FailingFibAction(9);
998                      invokeAll(g);
999                      shouldThrow();
1000                  } catch (FJException success) {
1001 +                    checkCompletedAbnormally(g, success);
1002                  }
1003              }};
1004 <        mainPool.invoke(a);
1004 >        testInvokeOnPool(mainPool(), a);
1005      }
1006  
1007      /**
1008       * invokeAll(tasks) with > 2 argument throws exception if any task does
1009       */
1010      public void testAbnormalInvokeAll3() {
1011 <        RecursiveAction a = new RecursiveAction() {
1012 <            public void compute() {
1011 >        RecursiveAction a = new CheckedRecursiveAction() {
1012 >            protected void realCompute() {
1013 >                FibAction f = new FibAction(8);
1014 >                FailingFibAction g = new FailingFibAction(9);
1015 >                FibAction h = new FibAction(7);
1016                  try {
673                    FibAction f = new FibAction(8);
674                    FailingFibAction g = new FailingFibAction(9);
675                    FibAction h = new FibAction(7);
1017                      invokeAll(f, g, h);
1018                      shouldThrow();
1019                  } catch (FJException success) {
1020 +                    checkCompletedAbnormally(g, success);
1021                  }
1022              }};
1023 <        mainPool.invoke(a);
1023 >        testInvokeOnPool(mainPool(), a);
1024      }
1025  
1026      /**
1027       * invokeAll(collection) throws exception if any task does
1028       */
1029      public void testAbnormalInvokeAllCollection() {
1030 <        RecursiveAction a = new RecursiveAction() {
1031 <            public void compute() {
1030 >        RecursiveAction a = new CheckedRecursiveAction() {
1031 >            protected void realCompute() {
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                  try {
691                    FailingFibAction f = new FailingFibAction(8);
692                    FibAction g = new FibAction(9);
693                    FibAction h = new FibAction(7);
694                    HashSet set = new HashSet();
695                    set.add(f);
696                    set.add(g);
697                    set.add(h);
1040                      invokeAll(set);
1041                      shouldThrow();
1042                  } catch (FJException success) {
1043 +                    checkCompletedAbnormally(f, success);
1044                  }
1045              }};
1046 <        mainPool.invoke(a);
1046 >        testInvokeOnPool(mainPool(), a);
1047      }
1048  
1049      /**
# Line 708 | Line 1051 | public class RecursiveActionTest extends
1051       * and suppresses execution
1052       */
1053      public void testTryUnfork() {
1054 <        RecursiveAction a = new RecursiveAction() {
1055 <            public void compute() {
1054 >        RecursiveAction a = new CheckedRecursiveAction() {
1055 >            protected void realCompute() {
1056                  FibAction g = new FibAction(9);
1057 <                g.fork();
1057 >                assertSame(g, g.fork());
1058                  FibAction f = new FibAction(8);
1059 <                f.fork();
1060 <                threadAssertTrue(f.tryUnfork());
1059 >                assertSame(f, f.fork());
1060 >                assertTrue(f.tryUnfork());
1061                  helpQuiesce();
1062 <                threadAssertFalse(f.isDone());
1063 <                threadAssertTrue(g.isDone());
1062 >                checkNotDone(f);
1063 >                checkCompletedNormally(g);
1064              }};
1065 <        singletonPool.invoke(a);
1065 >        testInvokeOnPool(singletonPool(), a);
1066      }
1067  
1068      /**
# Line 727 | Line 1070 | public class RecursiveActionTest extends
1070       * there are more tasks than threads
1071       */
1072      public void testGetSurplusQueuedTaskCount() {
1073 <        RecursiveAction a = new RecursiveAction() {
1074 <            public void compute() {
1073 >        RecursiveAction a = new CheckedRecursiveAction() {
1074 >            protected void realCompute() {
1075                  FibAction h = new FibAction(7);
1076 <                h.fork();
1076 >                assertSame(h, h.fork());
1077                  FibAction g = new FibAction(9);
1078 <                g.fork();
1078 >                assertSame(g, g.fork());
1079                  FibAction f = new FibAction(8);
1080 <                f.fork();
1081 <                threadAssertTrue(getSurplusQueuedTaskCount() > 0);
1080 >                assertSame(f, f.fork());
1081 >                assertTrue(getSurplusQueuedTaskCount() > 0);
1082                  helpQuiesce();
1083 +                assertEquals(0, getSurplusQueuedTaskCount());
1084 +                checkCompletedNormally(f);
1085 +                checkCompletedNormally(g);
1086 +                checkCompletedNormally(h);
1087              }};
1088 <        singletonPool.invoke(a);
1088 >        testInvokeOnPool(singletonPool(), a);
1089      }
1090  
1091      /**
1092       * peekNextLocalTask returns most recent unexecuted task.
1093       */
1094      public void testPeekNextLocalTask() {
1095 <        RecursiveAction a = new RecursiveAction() {
1096 <            public void compute() {
1095 >        RecursiveAction a = new CheckedRecursiveAction() {
1096 >            protected void realCompute() {
1097                  FibAction g = new FibAction(9);
1098 <                g.fork();
1098 >                assertSame(g, g.fork());
1099                  FibAction f = new FibAction(8);
1100 <                f.fork();
1101 <                threadAssertTrue(peekNextLocalTask() == f);
1102 <                f.join();
1103 <                threadAssertTrue(f.isDone());
1100 >                assertSame(f, f.fork());
1101 >                assertSame(f, peekNextLocalTask());
1102 >                assertNull(f.join());
1103 >                checkCompletedNormally(f);
1104                  helpQuiesce();
1105 +                checkCompletedNormally(f);
1106 +                checkCompletedNormally(g);
1107              }};
1108 <        singletonPool.invoke(a);
1108 >        testInvokeOnPool(singletonPool(), a);
1109      }
1110  
1111      /**
# Line 764 | Line 1113 | public class RecursiveActionTest extends
1113       * without executing it
1114       */
1115      public void testPollNextLocalTask() {
1116 <        RecursiveAction a = new RecursiveAction() {
1117 <            public void compute() {
1116 >        RecursiveAction a = new CheckedRecursiveAction() {
1117 >            protected void realCompute() {
1118                  FibAction g = new FibAction(9);
1119 <                g.fork();
1119 >                assertSame(g, g.fork());
1120                  FibAction f = new FibAction(8);
1121 <                f.fork();
1122 <                threadAssertTrue(pollNextLocalTask() == f);
1121 >                assertSame(f, f.fork());
1122 >                assertSame(f, pollNextLocalTask());
1123                  helpQuiesce();
1124 <                threadAssertFalse(f.isDone());
1124 >                checkNotDone(f);
1125 >                checkCompletedNormally(g);
1126              }};
1127 <        singletonPool.invoke(a);
1127 >        testInvokeOnPool(singletonPool(), a);
1128      }
1129  
1130      /**
1131 <     * pollTask returns an unexecuted task
782 <     * without executing it
1131 >     * pollTask returns an unexecuted task without executing it
1132       */
1133      public void testPollTask() {
1134 <        RecursiveAction a = new RecursiveAction() {
1135 <            public void compute() {
1134 >        RecursiveAction a = new CheckedRecursiveAction() {
1135 >            protected void realCompute() {
1136                  FibAction g = new FibAction(9);
1137 <                g.fork();
1137 >                assertSame(g, g.fork());
1138                  FibAction f = new FibAction(8);
1139 <                f.fork();
1140 <                threadAssertTrue(pollTask() == f);
1139 >                assertSame(f, f.fork());
1140 >                assertSame(f, pollTask());
1141                  helpQuiesce();
1142 <                threadAssertFalse(f.isDone());
1143 <                threadAssertTrue(g.isDone());
1142 >                checkNotDone(f);
1143 >                checkCompletedNormally(g);
1144              }};
1145 <        singletonPool.invoke(a);
1145 >        testInvokeOnPool(singletonPool(), a);
1146      }
1147  
1148      /**
1149       * peekNextLocalTask returns least recent unexecuted task in async mode
1150       */
1151      public void testPeekNextLocalTaskAsync() {
1152 <        RecursiveAction a = new RecursiveAction() {
1153 <            public void compute() {
1152 >        RecursiveAction a = new CheckedRecursiveAction() {
1153 >            protected void realCompute() {
1154                  FibAction g = new FibAction(9);
1155 <                g.fork();
1155 >                assertSame(g, g.fork());
1156                  FibAction f = new FibAction(8);
1157 <                f.fork();
1158 <                threadAssertTrue(peekNextLocalTask() == g);
1159 <                f.join();
1157 >                assertSame(f, f.fork());
1158 >                assertSame(g, peekNextLocalTask());
1159 >                assertNull(f.join());
1160                  helpQuiesce();
1161 <                threadAssertTrue(f.isDone());
1161 >                checkCompletedNormally(f);
1162 >                checkCompletedNormally(g);
1163              }};
1164 <        asyncSingletonPool.invoke(a);
1164 >        testInvokeOnPool(asyncSingletonPool(), a);
1165      }
1166  
1167      /**
1168 <     * pollNextLocalTask returns least recent unexecuted task
1169 <     * without executing it, in async mode
1168 >     * pollNextLocalTask returns least recent unexecuted task without
1169 >     * executing it, in async mode
1170       */
1171      public void testPollNextLocalTaskAsync() {
1172 <        RecursiveAction a = new RecursiveAction() {
1173 <            public void compute() {
1172 >        RecursiveAction a = new CheckedRecursiveAction() {
1173 >            protected void realCompute() {
1174                  FibAction g = new FibAction(9);
1175 <                g.fork();
1175 >                assertSame(g, g.fork());
1176                  FibAction f = new FibAction(8);
1177 <                f.fork();
1178 <                threadAssertTrue(pollNextLocalTask() == g);
1177 >                assertSame(f, f.fork());
1178 >                assertSame(g, pollNextLocalTask());
1179                  helpQuiesce();
1180 <                threadAssertTrue(f.isDone());
1181 <                threadAssertFalse(g.isDone());
1180 >                checkCompletedNormally(f);
1181 >                checkNotDone(g);
1182              }};
1183 <        asyncSingletonPool.invoke(a);
1183 >        testInvokeOnPool(asyncSingletonPool(), a);
1184      }
1185  
1186      /**
1187 <     * pollTask returns an unexecuted task
1188 <     * without executing it, in async mode
1187 >     * pollTask returns an unexecuted task without executing it, in
1188 >     * async mode
1189       */
1190      public void testPollTaskAsync() {
1191 <        RecursiveAction a = new RecursiveAction() {
1192 <            public void compute() {
1191 >        RecursiveAction a = new CheckedRecursiveAction() {
1192 >            protected void realCompute() {
1193                  FibAction g = new FibAction(9);
1194 <                g.fork();
1194 >                assertSame(g, g.fork());
1195                  FibAction f = new FibAction(8);
1196 <                f.fork();
1197 <                threadAssertTrue(pollTask() == g);
1196 >                assertSame(f, f.fork());
1197 >                assertSame(g, pollTask());
1198                  helpQuiesce();
1199 <                threadAssertTrue(f.isDone());
1200 <                threadAssertFalse(g.isDone());
1199 >                checkCompletedNormally(f);
1200 >                checkNotDone(g);
1201              }};
1202 <        asyncSingletonPool.invoke(a);
1202 >        testInvokeOnPool(asyncSingletonPool(), a);
1203 >    }
1204 >
1205 >    /** Demo from RecursiveAction javadoc */
1206 >    static class SortTask extends RecursiveAction {
1207 >        final long[] array; final int lo, hi;
1208 >        SortTask(long[] array, int lo, int hi) {
1209 >            this.array = array; this.lo = lo; this.hi = hi;
1210 >        }
1211 >        SortTask(long[] array) { this(array, 0, array.length); }
1212 >        protected void compute() {
1213 >            if (hi - lo < THRESHOLD)
1214 >                sortSequentially(lo, hi);
1215 >            else {
1216 >                int mid = (lo + hi) >>> 1;
1217 >                invokeAll(new SortTask(array, lo, mid),
1218 >                          new SortTask(array, mid, hi));
1219 >                merge(lo, mid, hi);
1220 >            }
1221 >        }
1222 >        // implementation details follow:
1223 >        static final int THRESHOLD = 100;
1224 >        void sortSequentially(int lo, int hi) {
1225 >            Arrays.sort(array, lo, hi);
1226 >        }
1227 >        void merge(int lo, int mid, int hi) {
1228 >            long[] buf = Arrays.copyOfRange(array, lo, mid);
1229 >            for (int i = 0, j = lo, k = mid; i < buf.length; j++)
1230 >                array[j] = (k == hi || buf[i] < array[k]) ?
1231 >                    buf[i++] : array[k++];
1232 >        }
1233      }
1234  
1235 +    /**
1236 +     * SortTask demo works as advertised
1237 +     */
1238 +    public void testSortTaskDemo() {
1239 +        ThreadLocalRandom rnd = ThreadLocalRandom.current();
1240 +        long[] array = new long[1007];
1241 +        for (int i = 0; i < array.length; i++)
1242 +            array[i] = rnd.nextLong();
1243 +        long[] arrayClone = array.clone();
1244 +        testInvokeOnPool(mainPool(), new SortTask(array));
1245 +        Arrays.sort(arrayClone);
1246 +        assertTrue(Arrays.equals(array, arrayClone));
1247 +    }
1248   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines