ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck-jsr166e/RecursiveActionTest.java
Revision: 1.1
Committed: Sun Jul 14 19:55:05 2013 UTC (10 years, 10 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Log Message:
backport jsr166e to run on jdk6; backport all applicable tck tests from tck to tck-jsr166e

File Contents

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