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.55 by jsr166, Sun Jul 22 21:09:02 2018 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines