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.20 by jsr166, Sun Nov 21 08:35:40 2010 UTC vs.
Revision 1.53 by jsr166, Sun Jan 7 22:59:18 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;
17 > import java.util.concurrent.SynchronousQueue;
18 > import java.util.concurrent.ThreadLocalRandom;
19   import java.util.concurrent.TimeoutException;
20 < import static java.util.concurrent.TimeUnit.SECONDS;
21 < import java.util.HashSet;
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 40 | Line 46 | public class RecursiveActionTest extends
46      }
47  
48      private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
49 <        try {
49 >        try (PoolCleaner cleaner = cleaner(pool)) {
50              checkNotDone(a);
51  
52              assertNull(pool.invoke(a));
53  
54              checkCompletedNormally(a);
49        } finally {
50            joinPool(pool);
55          }
56      }
57  
# Line 59 | Line 63 | public class RecursiveActionTest extends
63          assertNull(a.getException());
64          assertNull(a.getRawResult());
65  
66 <        if (! (Thread.currentThread() instanceof ForkJoinWorkerThread)) {
66 >        if (! ForkJoinTask.inForkJoinPool()) {
67              Thread.currentThread().interrupt();
68              try {
69                  a.get();
# Line 69 | Line 73 | public class RecursiveActionTest extends
73  
74              Thread.currentThread().interrupt();
75              try {
76 <                a.get(5L, SECONDS);
76 >                a.get(randomTimeout(), randomTimeUnit());
77                  shouldThrow();
78              } catch (InterruptedException success) {
79              } catch (Throwable fail) { threadUnexpectedException(fail); }
80          }
81  
82          try {
83 <            a.get(0L, SECONDS);
83 >            a.get(randomExpiredTimeout(), randomTimeUnit());
84              shouldThrow();
85          } catch (TimeoutException success) {
86          } catch (Throwable fail) { threadUnexpectedException(fail); }
# Line 90 | Line 94 | public class RecursiveActionTest extends
94          assertNull(a.getException());
95          assertNull(a.getRawResult());
96          assertNull(a.join());
97 +        assertFalse(a.cancel(false));
98 +        assertFalse(a.cancel(true));
99          try {
100              assertNull(a.get());
101 <        } catch (Throwable fail) { threadUnexpectedException(fail); }
96 <        try {
97 <            assertNull(a.get(5L, SECONDS));
101 >            assertNull(a.get(randomTimeout(), randomTimeUnit()));
102          } catch (Throwable fail) { threadUnexpectedException(fail); }
103      }
104  
# Line 119 | Line 123 | public class RecursiveActionTest extends
123          } catch (Throwable fail) { threadUnexpectedException(fail); }
124  
125          try {
126 <            a.get(5L, SECONDS);
126 >            a.get(randomTimeout(), randomTimeUnit());
127              shouldThrow();
128          } catch (CancellationException success) {
129          } catch (Throwable fail) { threadUnexpectedException(fail); }
130      }
131  
132 <    void checkTaskThrew(RecursiveAction a, Throwable t) {
132 >    void checkCompletedAbnormally(RecursiveAction a, Throwable t) {
133          assertTrue(a.isDone());
134          assertFalse(a.isCancelled());
135          assertFalse(a.isCompletedNormally());
136          assertTrue(a.isCompletedAbnormally());
137 <        assertSame(t, a.getException());
137 >        assertSame(t.getClass(), a.getException().getClass());
138          assertNull(a.getRawResult());
139 +        assertFalse(a.cancel(false));
140 +        assertFalse(a.cancel(true));
141  
142          try {
143              a.join();
144              shouldThrow();
145          } catch (Throwable expected) {
146 <            assertSame(t, expected);
146 >            assertSame(expected.getClass(), t.getClass());
147          }
148  
149          try {
150              a.get();
151              shouldThrow();
152          } catch (ExecutionException success) {
153 <            assertSame(t, success.getCause());
153 >            assertSame(t.getClass(), success.getCause().getClass());
154          } catch (Throwable fail) { threadUnexpectedException(fail); }
155  
156          try {
157 <            a.get(5L, SECONDS);
157 >            a.get(randomTimeout(), randomTimeUnit());
158              shouldThrow();
159          } catch (ExecutionException success) {
160 <            assertSame(t, success.getCause());
160 >            assertSame(t.getClass(), success.getCause().getClass());
161          } catch (Throwable fail) { threadUnexpectedException(fail); }
162      }
163  
164 <    static final class FJException extends RuntimeException {
165 <        FJException() { super(); }
164 >    public static final class FJException extends RuntimeException {
165 >        public FJException() { super(); }
166 >        public FJException(Throwable cause) { super(cause); }
167      }
168  
169 <    // A simple recursive action for testing
169 >    /** A simple recursive action for testing. */
170      final class FibAction extends CheckedRecursiveAction {
171          final int number;
172          int result;
173          FibAction(int n) { number = n; }
174 <        public void realCompute() {
174 >        protected void realCompute() {
175              int n = number;
176              if (n <= 1)
177                  result = n;
# Line 177 | Line 184 | public class RecursiveActionTest extends
184          }
185      }
186  
187 <    // A recursive action failing in base case
187 >    /** A recursive action failing in base case. */
188      static final class FailingFibAction extends RecursiveAction {
189          final int number;
190          int result;
# Line 202 | Line 209 | public class RecursiveActionTest extends
209       */
210      public void testInvoke() {
211          RecursiveAction a = new CheckedRecursiveAction() {
212 <            public void realCompute() {
212 >            protected void realCompute() {
213                  FibAction f = new FibAction(8);
214                  assertNull(f.invoke());
215                  assertEquals(21, f.result);
# Line 218 | Line 225 | public class RecursiveActionTest extends
225       */
226      public void testQuietlyInvoke() {
227          RecursiveAction a = new CheckedRecursiveAction() {
228 <            public void realCompute() {
228 >            protected void realCompute() {
229                  FibAction f = new FibAction(8);
230                  f.quietlyInvoke();
231                  assertEquals(21, f.result);
# Line 232 | Line 239 | public class RecursiveActionTest extends
239       */
240      public void testForkJoin() {
241          RecursiveAction a = new CheckedRecursiveAction() {
242 <            public void realCompute() {
242 >            protected void realCompute() {
243                  FibAction f = new FibAction(8);
244                  assertSame(f, f.fork());
245                  assertNull(f.join());
# Line 243 | Line 250 | public class RecursiveActionTest extends
250      }
251  
252      /**
253 +     * join/quietlyJoin of a forked task succeeds in the presence of interrupts
254 +     */
255 +    public void testJoinIgnoresInterrupts() {
256 +        RecursiveAction a = new CheckedRecursiveAction() {
257 +            protected void realCompute() {
258 +                FibAction f = new FibAction(8);
259 +                final Thread currentThread = Thread.currentThread();
260 +
261 +                // test join()
262 +                assertSame(f, f.fork());
263 +                currentThread.interrupt();
264 +                assertNull(f.join());
265 +                Thread.interrupted();
266 +                assertEquals(21, f.result);
267 +                checkCompletedNormally(f);
268 +
269 +                f = new FibAction(8);
270 +                f.cancel(true);
271 +                assertSame(f, f.fork());
272 +                currentThread.interrupt();
273 +                try {
274 +                    f.join();
275 +                    shouldThrow();
276 +                } catch (CancellationException success) {
277 +                    Thread.interrupted();
278 +                    checkCancelled(f);
279 +                }
280 +
281 +                f = new FibAction(8);
282 +                f.completeExceptionally(new FJException());
283 +                assertSame(f, f.fork());
284 +                currentThread.interrupt();
285 +                try {
286 +                    f.join();
287 +                    shouldThrow();
288 +                } catch (FJException success) {
289 +                    Thread.interrupted();
290 +                    checkCompletedAbnormally(f, success);
291 +                }
292 +
293 +                // test quietlyJoin()
294 +                f = new FibAction(8);
295 +                assertSame(f, f.fork());
296 +                currentThread.interrupt();
297 +                f.quietlyJoin();
298 +                Thread.interrupted();
299 +                assertEquals(21, f.result);
300 +                checkCompletedNormally(f);
301 +
302 +                f = new FibAction(8);
303 +                f.cancel(true);
304 +                assertSame(f, f.fork());
305 +                currentThread.interrupt();
306 +                f.quietlyJoin();
307 +                Thread.interrupted();
308 +                checkCancelled(f);
309 +
310 +                f = new FibAction(8);
311 +                f.completeExceptionally(new FJException());
312 +                assertSame(f, f.fork());
313 +                currentThread.interrupt();
314 +                f.quietlyJoin();
315 +                Thread.interrupted();
316 +                checkCompletedAbnormally(f, f.getException());
317 +            }};
318 +        testInvokeOnPool(mainPool(), a);
319 +        a.reinitialize();
320 +        testInvokeOnPool(singletonPool(), a);
321 +    }
322 +
323 +    /**
324 +     * join/quietlyJoin of a forked task when not in ForkJoinPool
325 +     * succeeds in the presence of interrupts
326 +     */
327 +    public void testJoinIgnoresInterruptsOutsideForkJoinPool() {
328 +        final SynchronousQueue<FibAction[]> sq = new SynchronousQueue<>();
329 +        RecursiveAction a = new CheckedRecursiveAction() {
330 +            protected void realCompute() throws InterruptedException {
331 +                FibAction[] fibActions = new FibAction[6];
332 +                for (int i = 0; i < fibActions.length; i++)
333 +                    fibActions[i] = new FibAction(8);
334 +
335 +                fibActions[1].cancel(false);
336 +                fibActions[2].completeExceptionally(new FJException());
337 +                fibActions[4].cancel(true);
338 +                fibActions[5].completeExceptionally(new FJException());
339 +
340 +                for (int i = 0; i < fibActions.length; i++)
341 +                    fibActions[i].fork();
342 +
343 +                sq.put(fibActions);
344 +
345 +                helpQuiesce();
346 +            }};
347 +
348 +        Runnable r = new CheckedRunnable() {
349 +            public void realRun() throws InterruptedException {
350 +                FibAction[] fibActions = sq.take();
351 +                FibAction f;
352 +                final Thread currentThread = Thread.currentThread();
353 +
354 +                // test join() ------------
355 +
356 +                f = fibActions[0];
357 +                assertFalse(ForkJoinTask.inForkJoinPool());
358 +                currentThread.interrupt();
359 +                assertNull(f.join());
360 +                assertTrue(Thread.interrupted());
361 +                assertEquals(21, f.result);
362 +                checkCompletedNormally(f);
363 +
364 +                f = fibActions[1];
365 +                currentThread.interrupt();
366 +                try {
367 +                    f.join();
368 +                    shouldThrow();
369 +                } catch (CancellationException success) {
370 +                    assertTrue(Thread.interrupted());
371 +                    checkCancelled(f);
372 +                }
373 +
374 +                f = fibActions[2];
375 +                currentThread.interrupt();
376 +                try {
377 +                    f.join();
378 +                    shouldThrow();
379 +                } catch (FJException success) {
380 +                    assertTrue(Thread.interrupted());
381 +                    checkCompletedAbnormally(f, success);
382 +                }
383 +
384 +                // test quietlyJoin() ---------
385 +
386 +                f = fibActions[3];
387 +                currentThread.interrupt();
388 +                f.quietlyJoin();
389 +                assertTrue(Thread.interrupted());
390 +                assertEquals(21, f.result);
391 +                checkCompletedNormally(f);
392 +
393 +                f = fibActions[4];
394 +                currentThread.interrupt();
395 +                f.quietlyJoin();
396 +                assertTrue(Thread.interrupted());
397 +                checkCancelled(f);
398 +
399 +                f = fibActions[5];
400 +                currentThread.interrupt();
401 +                f.quietlyJoin();
402 +                assertTrue(Thread.interrupted());
403 +                assertTrue(f.getException() instanceof FJException);
404 +                checkCompletedAbnormally(f, f.getException());
405 +            }};
406 +
407 +        Thread t;
408 +
409 +        t = newStartedThread(r);
410 +        testInvokeOnPool(mainPool(), a);
411 +        awaitTermination(t);
412 +
413 +        a.reinitialize();
414 +        t = newStartedThread(r);
415 +        testInvokeOnPool(singletonPool(), a);
416 +        awaitTermination(t);
417 +    }
418 +
419 +    /**
420       * get of a forked task returns when task completes
421       */
422      public void testForkGet() {
423          RecursiveAction a = new CheckedRecursiveAction() {
424 <            public void realCompute() throws Exception {
424 >            protected void realCompute() throws Exception {
425                  FibAction f = new FibAction(8);
426                  assertSame(f, f.fork());
427                  assertNull(f.get());
# Line 262 | Line 436 | public class RecursiveActionTest extends
436       */
437      public void testForkTimedGet() {
438          RecursiveAction a = new CheckedRecursiveAction() {
439 <            public void realCompute() throws Exception {
439 >            protected void realCompute() throws Exception {
440                  FibAction f = new FibAction(8);
441                  assertSame(f, f.fork());
442 <                assertNull(f.get(5L, SECONDS));
442 >                assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
443                  assertEquals(21, f.result);
444                  checkCompletedNormally(f);
445              }};
# Line 277 | Line 451 | public class RecursiveActionTest extends
451       */
452      public void testForkTimedGetNPE() {
453          RecursiveAction a = new CheckedRecursiveAction() {
454 <            public void realCompute() throws Exception {
454 >            protected void realCompute() throws Exception {
455                  FibAction f = new FibAction(8);
456                  assertSame(f, f.fork());
457                  try {
458 <                    f.get(5L, null);
458 >                    f.get(randomTimeout(), null);
459                      shouldThrow();
460                  } catch (NullPointerException success) {}
461              }};
# Line 293 | Line 467 | public class RecursiveActionTest extends
467       */
468      public void testForkQuietlyJoin() {
469          RecursiveAction a = new CheckedRecursiveAction() {
470 <            public void realCompute() {
470 >            protected void realCompute() {
471                  FibAction f = new FibAction(8);
472                  assertSame(f, f.fork());
473                  f.quietlyJoin();
# Line 303 | Line 477 | public class RecursiveActionTest extends
477          testInvokeOnPool(mainPool(), a);
478      }
479  
306
480      /**
481       * helpQuiesce returns when tasks are complete.
482       * getQueuedTaskCount returns 0 when quiescent
483       */
484      public void testForkHelpQuiesce() {
485          RecursiveAction a = new CheckedRecursiveAction() {
486 <            public void realCompute() {
486 >            protected void realCompute() {
487                  FibAction f = new FibAction(8);
488                  assertSame(f, f.fork());
489 <                f.helpQuiesce();
489 >                helpQuiesce();
490 >                while (!f.isDone()) // wait out race
491 >                    ;
492                  assertEquals(21, f.result);
493                  assertEquals(0, getQueuedTaskCount());
494                  checkCompletedNormally(f);
# Line 321 | Line 496 | public class RecursiveActionTest extends
496          testInvokeOnPool(mainPool(), a);
497      }
498  
324
499      /**
500       * invoke task throws exception when task completes abnormally
501       */
502      public void testAbnormalInvoke() {
503          RecursiveAction a = new CheckedRecursiveAction() {
504 <            public void realCompute() {
504 >            protected void realCompute() {
505                  FailingFibAction f = new FailingFibAction(8);
506                  try {
507                      f.invoke();
508                      shouldThrow();
509                  } catch (FJException success) {
510 <                    checkTaskThrew(f, success);
510 >                    checkCompletedAbnormally(f, success);
511                  }
512              }};
513          testInvokeOnPool(mainPool(), a);
# Line 344 | Line 518 | public class RecursiveActionTest extends
518       */
519      public void testAbnormalQuietlyInvoke() {
520          RecursiveAction a = new CheckedRecursiveAction() {
521 <            public void realCompute() {
521 >            protected void realCompute() {
522                  FailingFibAction f = new FailingFibAction(8);
523                  f.quietlyInvoke();
524                  assertTrue(f.getException() instanceof FJException);
525 <                checkTaskThrew(f, f.getException());
525 >                checkCompletedAbnormally(f, f.getException());
526              }};
527          testInvokeOnPool(mainPool(), a);
528      }
# Line 358 | Line 532 | public class RecursiveActionTest extends
532       */
533      public void testAbnormalForkJoin() {
534          RecursiveAction a = new CheckedRecursiveAction() {
535 <            public void realCompute() {
535 >            protected void realCompute() {
536                  FailingFibAction f = new FailingFibAction(8);
537                  assertSame(f, f.fork());
538                  try {
539                      f.join();
540                      shouldThrow();
541                  } catch (FJException success) {
542 <                    checkTaskThrew(f, success);
542 >                    checkCompletedAbnormally(f, success);
543                  }
544              }};
545          testInvokeOnPool(mainPool(), a);
# Line 376 | Line 550 | public class RecursiveActionTest extends
550       */
551      public void testAbnormalForkGet() {
552          RecursiveAction a = new CheckedRecursiveAction() {
553 <            public void realCompute() throws Exception {
553 >            protected void realCompute() throws Exception {
554                  FailingFibAction f = new FailingFibAction(8);
555                  assertSame(f, f.fork());
556                  try {
557                      f.get();
558                      shouldThrow();
559                  } catch (ExecutionException success) {
560 <                    checkTaskThrew(f, success.getCause());
560 >                    Throwable cause = success.getCause();
561 >                    assertTrue(cause instanceof FJException);
562 >                    checkCompletedAbnormally(f, cause);
563                  }
564              }};
565          testInvokeOnPool(mainPool(), a);
# Line 394 | Line 570 | public class RecursiveActionTest extends
570       */
571      public void testAbnormalForkTimedGet() {
572          RecursiveAction a = new CheckedRecursiveAction() {
573 <            public void realCompute() throws Exception {
573 >            protected void realCompute() throws Exception {
574                  FailingFibAction f = new FailingFibAction(8);
575                  assertSame(f, f.fork());
576                  try {
577 <                    f.get(5L, TimeUnit.SECONDS);
577 >                    f.get(LONG_DELAY_MS, MILLISECONDS);
578                      shouldThrow();
579                  } catch (ExecutionException success) {
580 <                    checkTaskThrew(f, success.getCause());
580 >                    Throwable cause = success.getCause();
581 >                    assertTrue(cause instanceof FJException);
582 >                    checkCompletedAbnormally(f, cause);
583                  }
584              }};
585          testInvokeOnPool(mainPool(), a);
# Line 412 | Line 590 | public class RecursiveActionTest extends
590       */
591      public void testAbnormalForkQuietlyJoin() {
592          RecursiveAction a = new CheckedRecursiveAction() {
593 <            public void realCompute() {
593 >            protected void realCompute() {
594                  FailingFibAction f = new FailingFibAction(8);
595                  assertSame(f, f.fork());
596                  f.quietlyJoin();
597                  assertTrue(f.getException() instanceof FJException);
598 <                checkTaskThrew(f, f.getException());
598 >                checkCompletedAbnormally(f, f.getException());
599              }};
600          testInvokeOnPool(mainPool(), a);
601      }
# Line 427 | Line 605 | public class RecursiveActionTest extends
605       */
606      public void testCancelledInvoke() {
607          RecursiveAction a = new CheckedRecursiveAction() {
608 <            public void realCompute() {
608 >            protected void realCompute() {
609                  FibAction f = new FibAction(8);
610                  assertTrue(f.cancel(true));
611                  try {
# Line 445 | Line 623 | public class RecursiveActionTest extends
623       */
624      public void testCancelledForkJoin() {
625          RecursiveAction a = new CheckedRecursiveAction() {
626 <            public void realCompute() {
626 >            protected void realCompute() {
627                  FibAction f = new FibAction(8);
628                  assertTrue(f.cancel(true));
629                  assertSame(f, f.fork());
# Line 464 | Line 642 | public class RecursiveActionTest extends
642       */
643      public void testCancelledForkGet() {
644          RecursiveAction a = new CheckedRecursiveAction() {
645 <            public void realCompute() throws Exception {
645 >            protected void realCompute() throws Exception {
646                  FibAction f = new FibAction(8);
647                  assertTrue(f.cancel(true));
648                  assertSame(f, f.fork());
# Line 483 | Line 661 | public class RecursiveActionTest extends
661       */
662      public void testCancelledForkTimedGet() {
663          RecursiveAction a = new CheckedRecursiveAction() {
664 <            public void realCompute() throws Exception {
664 >            protected void realCompute() throws Exception {
665                  FibAction f = new FibAction(8);
666                  assertTrue(f.cancel(true));
667                  assertSame(f, f.fork());
668                  try {
669 <                    f.get(5L, SECONDS);
669 >                    f.get(LONG_DELAY_MS, MILLISECONDS);
670                      shouldThrow();
671                  } catch (CancellationException success) {
672                      checkCancelled(f);
# Line 502 | Line 680 | public class RecursiveActionTest extends
680       */
681      public void testCancelledForkQuietlyJoin() {
682          RecursiveAction a = new CheckedRecursiveAction() {
683 <            public void realCompute() {
683 >            protected void realCompute() {
684                  FibAction f = new FibAction(8);
685                  assertTrue(f.cancel(true));
686                  assertSame(f, f.fork());
# Line 518 | Line 696 | public class RecursiveActionTest extends
696      public void testGetPool() {
697          final ForkJoinPool mainPool = mainPool();
698          RecursiveAction a = new CheckedRecursiveAction() {
699 <            public void realCompute() {
699 >            protected void realCompute() {
700                  assertSame(mainPool, getPool());
701              }};
702          testInvokeOnPool(mainPool, a);
# Line 529 | Line 707 | public class RecursiveActionTest extends
707       */
708      public void testGetPool2() {
709          RecursiveAction a = new CheckedRecursiveAction() {
710 <            public void realCompute() {
710 >            protected void realCompute() {
711                  assertNull(getPool());
712              }};
713          assertNull(a.invoke());
# Line 540 | Line 718 | public class RecursiveActionTest extends
718       */
719      public void testInForkJoinPool() {
720          RecursiveAction a = new CheckedRecursiveAction() {
721 <            public void realCompute() {
721 >            protected void realCompute() {
722                  assertTrue(inForkJoinPool());
723              }};
724          testInvokeOnPool(mainPool(), a);
# Line 551 | Line 729 | public class RecursiveActionTest extends
729       */
730      public void testInForkJoinPool2() {
731          RecursiveAction a = new CheckedRecursiveAction() {
732 <            public void realCompute() {
732 >            protected void realCompute() {
733                  assertFalse(inForkJoinPool());
734              }};
735          assertNull(a.invoke());
# Line 563 | Line 741 | public class RecursiveActionTest extends
741      public void testWorkerGetPool() {
742          final ForkJoinPool mainPool = mainPool();
743          RecursiveAction a = new CheckedRecursiveAction() {
744 <            public void realCompute() {
744 >            protected void realCompute() {
745                  ForkJoinWorkerThread w =
746                      (ForkJoinWorkerThread) Thread.currentThread();
747                  assertSame(mainPool, w.getPool());
# Line 577 | Line 755 | public class RecursiveActionTest extends
755      public void testWorkerGetPoolIndex() {
756          final ForkJoinPool mainPool = mainPool();
757          RecursiveAction a = new CheckedRecursiveAction() {
758 <            public void realCompute() {
758 >            protected void realCompute() {
759                  ForkJoinWorkerThread w =
760 <                    (ForkJoinWorkerThread)(Thread.currentThread());
760 >                    (ForkJoinWorkerThread) Thread.currentThread();
761                  assertTrue(w.getPoolIndex() >= 0);
762 <                assertTrue(w.getPoolIndex() < mainPool.getPoolSize());
762 >                // pool size can shrink after assigning index, so cannot check
763 >                // assertTrue(w.getPoolIndex() < mainPool.getPoolSize());
764              }};
765          testInvokeOnPool(mainPool, a);
766      }
767  
589
768      /**
769       * setRawResult(null) succeeds
770       */
771      public void testSetRawResult() {
772          RecursiveAction a = new CheckedRecursiveAction() {
773 <            public void realCompute() {
773 >            protected void realCompute() {
774                  setRawResult(null);
775 +                assertNull(getRawResult());
776              }};
777          assertNull(a.invoke());
778      }
779  
780      /**
781 <     * A reinitialized task may be re-invoked
781 >     * A reinitialized normally completed task may be re-invoked
782       */
783      public void testReinitialize() {
784          RecursiveAction a = new CheckedRecursiveAction() {
785 <            public void realCompute() {
785 >            protected void realCompute() {
786                  FibAction f = new FibAction(8);
787                  checkNotDone(f);
788  
# Line 619 | Line 798 | public class RecursiveActionTest extends
798      }
799  
800      /**
801 +     * A reinitialized abnormally completed task may be re-invoked
802 +     */
803 +    public void testReinitializeAbnormal() {
804 +        RecursiveAction a = new CheckedRecursiveAction() {
805 +            protected void realCompute() {
806 +                FailingFibAction f = new FailingFibAction(8);
807 +                checkNotDone(f);
808 +
809 +                for (int i = 0; i < 3; i++) {
810 +                    try {
811 +                        f.invoke();
812 +                        shouldThrow();
813 +                    } catch (FJException success) {
814 +                        checkCompletedAbnormally(f, success);
815 +                    }
816 +                    f.reinitialize();
817 +                    checkNotDone(f);
818 +                }
819 +            }};
820 +        testInvokeOnPool(mainPool(), a);
821 +    }
822 +
823 +    /**
824       * invoke task throws exception after invoking completeExceptionally
825       */
826      public void testCompleteExceptionally() {
827          RecursiveAction a = new CheckedRecursiveAction() {
828 <            public void realCompute() {
828 >            protected void realCompute() {
829                  FibAction f = new FibAction(8);
830                  f.completeExceptionally(new FJException());
831                  try {
832                      f.invoke();
833                      shouldThrow();
834                  } catch (FJException success) {
835 <                    checkTaskThrew(f, success);
835 >                    checkCompletedAbnormally(f, success);
836                  }
837              }};
838          testInvokeOnPool(mainPool(), a);
# Line 641 | Line 843 | public class RecursiveActionTest extends
843       */
844      public void testComplete() {
845          RecursiveAction a = new CheckedRecursiveAction() {
846 <            public void realCompute() {
846 >            protected void realCompute() {
847                  FibAction f = new FibAction(8);
848                  f.complete(null);
849                  assertNull(f.invoke());
# Line 656 | Line 858 | public class RecursiveActionTest extends
858       */
859      public void testInvokeAll2() {
860          RecursiveAction a = new CheckedRecursiveAction() {
861 <            public void realCompute() {
861 >            protected void realCompute() {
862                  FibAction f = new FibAction(8);
863                  FibAction g = new FibAction(9);
864                  invokeAll(f, g);
# Line 673 | Line 875 | public class RecursiveActionTest extends
875       */
876      public void testInvokeAll1() {
877          RecursiveAction a = new CheckedRecursiveAction() {
878 <            public void realCompute() {
878 >            protected void realCompute() {
879                  FibAction f = new FibAction(8);
880                  invokeAll(f);
881                  checkCompletedNormally(f);
# Line 687 | Line 889 | public class RecursiveActionTest extends
889       */
890      public void testInvokeAll3() {
891          RecursiveAction a = new CheckedRecursiveAction() {
892 <            public void realCompute() {
892 >            protected void realCompute() {
893                  FibAction f = new FibAction(8);
894                  FibAction g = new FibAction(9);
895                  FibAction h = new FibAction(7);
# Line 710 | Line 912 | public class RecursiveActionTest extends
912       */
913      public void testInvokeAllCollection() {
914          RecursiveAction a = new CheckedRecursiveAction() {
915 <            public void realCompute() {
915 >            protected void realCompute() {
916                  FibAction f = new FibAction(8);
917                  FibAction g = new FibAction(9);
918                  FibAction h = new FibAction(7);
# Line 732 | Line 934 | public class RecursiveActionTest extends
934          testInvokeOnPool(mainPool(), a);
935      }
936  
735
937      /**
938       * invokeAll(tasks) with any null task throws NPE
939       */
940      public void testInvokeAllNPE() {
941          RecursiveAction a = new CheckedRecursiveAction() {
942 <            public void realCompute() {
942 >            protected void realCompute() {
943                  FibAction f = new FibAction(8);
944                  FibAction g = new FibAction(9);
945                  FibAction h = null;
# Line 755 | Line 956 | public class RecursiveActionTest extends
956       */
957      public void testAbnormalInvokeAll2() {
958          RecursiveAction a = new CheckedRecursiveAction() {
959 <            public void realCompute() {
959 >            protected void realCompute() {
960                  FibAction f = new FibAction(8);
961                  FailingFibAction g = new FailingFibAction(9);
962                  try {
963                      invokeAll(f, g);
964                      shouldThrow();
965                  } catch (FJException success) {
966 <                    checkTaskThrew(g, success);
966 >                    checkCompletedAbnormally(g, success);
967                  }
968              }};
969          testInvokeOnPool(mainPool(), a);
# Line 773 | Line 974 | public class RecursiveActionTest extends
974       */
975      public void testAbnormalInvokeAll1() {
976          RecursiveAction a = new CheckedRecursiveAction() {
977 <            public void realCompute() {
977 >            protected void realCompute() {
978                  FailingFibAction g = new FailingFibAction(9);
979                  try {
980                      invokeAll(g);
981                      shouldThrow();
982                  } catch (FJException success) {
983 <                    checkTaskThrew(g, success);
983 >                    checkCompletedAbnormally(g, success);
984                  }
985              }};
986          testInvokeOnPool(mainPool(), a);
# Line 790 | Line 991 | public class RecursiveActionTest extends
991       */
992      public void testAbnormalInvokeAll3() {
993          RecursiveAction a = new CheckedRecursiveAction() {
994 <            public void realCompute() {
994 >            protected void realCompute() {
995                  FibAction f = new FibAction(8);
996                  FailingFibAction g = new FailingFibAction(9);
997                  FibAction h = new FibAction(7);
# Line 798 | Line 999 | public class RecursiveActionTest extends
999                      invokeAll(f, g, h);
1000                      shouldThrow();
1001                  } catch (FJException success) {
1002 <                    checkTaskThrew(g, success);
1002 >                    checkCompletedAbnormally(g, success);
1003                  }
1004              }};
1005          testInvokeOnPool(mainPool(), a);
# Line 809 | Line 1010 | public class RecursiveActionTest extends
1010       */
1011      public void testAbnormalInvokeAllCollection() {
1012          RecursiveAction a = new CheckedRecursiveAction() {
1013 <            public void realCompute() {
1013 >            protected void realCompute() {
1014                  FailingFibAction f = new FailingFibAction(8);
1015                  FibAction g = new FibAction(9);
1016                  FibAction h = new FibAction(7);
# Line 821 | Line 1022 | public class RecursiveActionTest extends
1022                      invokeAll(set);
1023                      shouldThrow();
1024                  } catch (FJException success) {
1025 <                    checkTaskThrew(f, success);
1025 >                    checkCompletedAbnormally(f, success);
1026                  }
1027              }};
1028          testInvokeOnPool(mainPool(), a);
# Line 833 | Line 1034 | public class RecursiveActionTest extends
1034       */
1035      public void testTryUnfork() {
1036          RecursiveAction a = new CheckedRecursiveAction() {
1037 <            public void realCompute() {
1037 >            protected void realCompute() {
1038                  FibAction g = new FibAction(9);
1039                  assertSame(g, g.fork());
1040                  FibAction f = new FibAction(8);
# Line 852 | Line 1053 | public class RecursiveActionTest extends
1053       */
1054      public void testGetSurplusQueuedTaskCount() {
1055          RecursiveAction a = new CheckedRecursiveAction() {
1056 <            public void realCompute() {
1056 >            protected void realCompute() {
1057                  FibAction h = new FibAction(7);
1058                  assertSame(h, h.fork());
1059                  FibAction g = new FibAction(9);
# Line 861 | Line 1062 | public class RecursiveActionTest extends
1062                  assertSame(f, f.fork());
1063                  assertTrue(getSurplusQueuedTaskCount() > 0);
1064                  helpQuiesce();
1065 +                assertEquals(0, getSurplusQueuedTaskCount());
1066                  checkCompletedNormally(f);
1067                  checkCompletedNormally(g);
1068                  checkCompletedNormally(h);
# Line 873 | Line 1075 | public class RecursiveActionTest extends
1075       */
1076      public void testPeekNextLocalTask() {
1077          RecursiveAction a = new CheckedRecursiveAction() {
1078 <            public void realCompute() {
1078 >            protected void realCompute() {
1079                  FibAction g = new FibAction(9);
1080                  assertSame(g, g.fork());
1081                  FibAction f = new FibAction(8);
# Line 894 | Line 1096 | public class RecursiveActionTest extends
1096       */
1097      public void testPollNextLocalTask() {
1098          RecursiveAction a = new CheckedRecursiveAction() {
1099 <            public void realCompute() {
1099 >            protected void realCompute() {
1100                  FibAction g = new FibAction(9);
1101                  assertSame(g, g.fork());
1102                  FibAction f = new FibAction(8);
# Line 912 | Line 1114 | public class RecursiveActionTest extends
1114       */
1115      public void testPollTask() {
1116          RecursiveAction a = new CheckedRecursiveAction() {
1117 <            public void realCompute() {
1117 >            protected void realCompute() {
1118                  FibAction g = new FibAction(9);
1119                  assertSame(g, g.fork());
1120                  FibAction f = new FibAction(8);
# Line 930 | Line 1132 | public class RecursiveActionTest extends
1132       */
1133      public void testPeekNextLocalTaskAsync() {
1134          RecursiveAction a = new CheckedRecursiveAction() {
1135 <            public void realCompute() {
1135 >            protected void realCompute() {
1136                  FibAction g = new FibAction(9);
1137                  assertSame(g, g.fork());
1138                  FibAction f = new FibAction(8);
# Line 950 | Line 1152 | public class RecursiveActionTest extends
1152       */
1153      public void testPollNextLocalTaskAsync() {
1154          RecursiveAction a = new CheckedRecursiveAction() {
1155 <            public void realCompute() {
1155 >            protected void realCompute() {
1156                  FibAction g = new FibAction(9);
1157                  assertSame(g, g.fork());
1158                  FibAction f = new FibAction(8);
# Line 969 | Line 1171 | public class RecursiveActionTest extends
1171       */
1172      public void testPollTaskAsync() {
1173          RecursiveAction a = new CheckedRecursiveAction() {
1174 <            public void realCompute() {
1174 >            protected void realCompute() {
1175                  FibAction g = new FibAction(9);
1176                  assertSame(g, g.fork());
1177                  FibAction f = new FibAction(8);
# Line 982 | Line 1184 | public class RecursiveActionTest extends
1184          testInvokeOnPool(asyncSingletonPool(), a);
1185      }
1186  
1187 +    /** Demo from RecursiveAction javadoc */
1188 +    static class SortTask extends RecursiveAction {
1189 +        final long[] array; final int lo, hi;
1190 +        SortTask(long[] array, int lo, int hi) {
1191 +            this.array = array; this.lo = lo; this.hi = hi;
1192 +        }
1193 +        SortTask(long[] array) { this(array, 0, array.length); }
1194 +        protected void compute() {
1195 +            if (hi - lo < THRESHOLD)
1196 +                sortSequentially(lo, hi);
1197 +            else {
1198 +                int mid = (lo + hi) >>> 1;
1199 +                invokeAll(new SortTask(array, lo, mid),
1200 +                          new SortTask(array, mid, hi));
1201 +                merge(lo, mid, hi);
1202 +            }
1203 +        }
1204 +        // implementation details follow:
1205 +        static final int THRESHOLD = 100;
1206 +        void sortSequentially(int lo, int hi) {
1207 +            Arrays.sort(array, lo, hi);
1208 +        }
1209 +        void merge(int lo, int mid, int hi) {
1210 +            long[] buf = Arrays.copyOfRange(array, lo, mid);
1211 +            for (int i = 0, j = lo, k = mid; i < buf.length; j++)
1212 +                array[j] = (k == hi || buf[i] < array[k]) ?
1213 +                    buf[i++] : array[k++];
1214 +        }
1215 +    }
1216 +
1217 +    /**
1218 +     * SortTask demo works as advertised
1219 +     */
1220 +    public void testSortTaskDemo() {
1221 +        ThreadLocalRandom rnd = ThreadLocalRandom.current();
1222 +        long[] array = new long[1007];
1223 +        for (int i = 0; i < array.length; i++)
1224 +            array[i] = rnd.nextLong();
1225 +        long[] arrayClone = array.clone();
1226 +        testInvokeOnPool(mainPool(), new SortTask(array));
1227 +        Arrays.sort(arrayClone);
1228 +        assertTrue(Arrays.equals(array, arrayClone));
1229 +    }
1230   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines