ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/RecursiveActionTest.java
Revision: 1.47
Committed: Tue Aug 16 23:02:57 2016 UTC (7 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.46: +26 -26 lines
Log Message:
rename myself to currentThread

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