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.40 by jsr166, Wed Dec 31 19:05:43 2014 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines