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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines