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.14 by jsr166, Mon Sep 13 07:51:18 2010 UTC vs.
Revision 1.55 by jsr166, Sun Jul 22 21:09:02 2018 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines