ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/CountedCompleterTest.java
Revision: 1.29
Committed: Mon Sep 12 17:49:12 2016 UTC (7 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.28: +1 -1 lines
Log Message:
improve code comment as suggested by reviewers

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.MILLISECONDS;
8 import static java.util.concurrent.TimeUnit.SECONDS;
9
10 import java.util.HashSet;
11 import java.util.concurrent.CancellationException;
12 import java.util.concurrent.CountedCompleter;
13 import java.util.concurrent.ExecutionException;
14 import java.util.concurrent.ForkJoinPool;
15 import java.util.concurrent.ForkJoinTask;
16 import java.util.concurrent.ThreadLocalRandom;
17 import java.util.concurrent.TimeoutException;
18 import java.util.concurrent.atomic.AtomicInteger;
19 import java.util.concurrent.atomic.AtomicReference;
20 import java.util.function.BiConsumer;
21 import java.util.function.Consumer;
22
23 import junit.framework.Test;
24 import junit.framework.TestSuite;
25
26 public class CountedCompleterTest extends JSR166TestCase {
27
28 public static void main(String[] args) {
29 main(suite(), args);
30 }
31
32 public static Test suite() {
33 return new TestSuite(CountedCompleterTest.class);
34 }
35
36 // Runs with "mainPool" use > 1 thread. singletonPool tests use 1
37 static final int mainPoolSize =
38 Math.max(2, Runtime.getRuntime().availableProcessors());
39
40 private static ForkJoinPool mainPool() {
41 return new ForkJoinPool(mainPoolSize);
42 }
43
44 private static ForkJoinPool singletonPool() {
45 return new ForkJoinPool(1);
46 }
47
48 private static ForkJoinPool asyncSingletonPool() {
49 return new ForkJoinPool(1,
50 ForkJoinPool.defaultForkJoinWorkerThreadFactory,
51 null, true);
52 }
53
54 private void testInvokeOnPool(ForkJoinPool pool, ForkJoinTask a) {
55 try (PoolCleaner cleaner = cleaner(pool)) {
56 assertFalse(a.isDone());
57 assertFalse(a.isCompletedNormally());
58 assertFalse(a.isCompletedAbnormally());
59 assertFalse(a.isCancelled());
60 assertNull(a.getException());
61 assertNull(a.getRawResult());
62
63 assertNull(pool.invoke(a));
64
65 assertTrue(a.isDone());
66 assertTrue(a.isCompletedNormally());
67 assertFalse(a.isCompletedAbnormally());
68 assertFalse(a.isCancelled());
69 assertNull(a.getException());
70 assertNull(a.getRawResult());
71 }
72 }
73
74 void checkNotDone(CountedCompleter a) {
75 assertFalse(a.isDone());
76 assertFalse(a.isCompletedNormally());
77 assertFalse(a.isCompletedAbnormally());
78 assertFalse(a.isCancelled());
79 assertNull(a.getException());
80 assertNull(a.getRawResult());
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(CountedCompleter<?> 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
97 {
98 Thread.currentThread().interrupt();
99 long startTime = System.nanoTime();
100 assertNull(a.join());
101 assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
102 Thread.interrupted();
103 }
104
105 {
106 Thread.currentThread().interrupt();
107 long startTime = System.nanoTime();
108 a.quietlyJoin(); // should be no-op
109 assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
110 Thread.interrupted();
111 }
112
113 assertFalse(a.cancel(false));
114 assertFalse(a.cancel(true));
115 try {
116 assertNull(a.get());
117 } catch (Throwable fail) { threadUnexpectedException(fail); }
118 try {
119 assertNull(a.get(5L, SECONDS));
120 } catch (Throwable fail) { threadUnexpectedException(fail); }
121 }
122
123 void checkCancelled(CountedCompleter a) {
124 assertTrue(a.isDone());
125 assertTrue(a.isCancelled());
126 assertFalse(a.isCompletedNormally());
127 assertTrue(a.isCompletedAbnormally());
128 assertTrue(a.getException() instanceof CancellationException);
129 assertNull(a.getRawResult());
130 assertTrue(a.cancel(false));
131 assertTrue(a.cancel(true));
132
133 try {
134 Thread.currentThread().interrupt();
135 a.join();
136 shouldThrow();
137 } catch (CancellationException success) {
138 } catch (Throwable fail) { threadUnexpectedException(fail); }
139 Thread.interrupted();
140
141 {
142 long startTime = System.nanoTime();
143 a.quietlyJoin(); // should be no-op
144 assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
145 }
146
147 try {
148 a.get();
149 shouldThrow();
150 } catch (CancellationException success) {
151 } catch (Throwable fail) { threadUnexpectedException(fail); }
152
153 try {
154 a.get(5L, SECONDS);
155 shouldThrow();
156 } catch (CancellationException success) {
157 } catch (Throwable fail) { threadUnexpectedException(fail); }
158 }
159
160 void checkCompletedAbnormally(CountedCompleter a, Throwable t) {
161 assertTrue(a.isDone());
162 assertFalse(a.isCancelled());
163 assertFalse(a.isCompletedNormally());
164 assertTrue(a.isCompletedAbnormally());
165 assertSame(t.getClass(), a.getException().getClass());
166 assertNull(a.getRawResult());
167 assertFalse(a.cancel(false));
168 assertFalse(a.cancel(true));
169
170 try {
171 Thread.currentThread().interrupt();
172 a.join();
173 shouldThrow();
174 } catch (Throwable expected) {
175 assertSame(t.getClass(), expected.getClass());
176 }
177 Thread.interrupted();
178
179 {
180 long startTime = System.nanoTime();
181 a.quietlyJoin(); // should be no-op
182 assertTrue(millisElapsedSince(startTime) < SMALL_DELAY_MS);
183 }
184
185 try {
186 a.get();
187 shouldThrow();
188 } catch (ExecutionException success) {
189 assertSame(t.getClass(), success.getCause().getClass());
190 } catch (Throwable fail) { threadUnexpectedException(fail); }
191
192 try {
193 a.get(5L, SECONDS);
194 shouldThrow();
195 } catch (ExecutionException success) {
196 assertSame(t.getClass(), success.getCause().getClass());
197 } catch (Throwable fail) { threadUnexpectedException(fail); }
198
199 try {
200 a.invoke();
201 shouldThrow();
202 } catch (Throwable success) {
203 assertSame(t, success);
204 }
205 }
206
207 public static final class FJException extends RuntimeException {
208 FJException() { super(); }
209 }
210
211 abstract class CheckedCC extends CountedCompleter<Object> {
212 final AtomicInteger computeN = new AtomicInteger(0);
213 final AtomicInteger onCompletionN = new AtomicInteger(0);
214 final AtomicInteger onExceptionalCompletionN = new AtomicInteger(0);
215 final AtomicInteger setRawResultN = new AtomicInteger(0);
216 final AtomicReference<Object> rawResult = new AtomicReference<Object>(null);
217 int computeN() { return computeN.get(); }
218 int onCompletionN() { return onCompletionN.get(); }
219 int onExceptionalCompletionN() { return onExceptionalCompletionN.get(); }
220 int setRawResultN() { return setRawResultN.get(); }
221
222 CheckedCC() { super(); }
223 CheckedCC(CountedCompleter p) { super(p); }
224 CheckedCC(CountedCompleter p, int n) { super(p, n); }
225 abstract void realCompute();
226 public final void compute() {
227 computeN.incrementAndGet();
228 realCompute();
229 }
230 public void onCompletion(CountedCompleter caller) {
231 onCompletionN.incrementAndGet();
232 super.onCompletion(caller);
233 }
234 public boolean onExceptionalCompletion(Throwable ex,
235 CountedCompleter caller) {
236 onExceptionalCompletionN.incrementAndGet();
237 assertNotNull(ex);
238 assertTrue(isCompletedAbnormally());
239 assertTrue(super.onExceptionalCompletion(ex, caller));
240 return true;
241 }
242 protected void setRawResult(Object t) {
243 setRawResultN.incrementAndGet();
244 rawResult.set(t);
245 super.setRawResult(t);
246 }
247 void checkIncomplete() {
248 assertEquals(0, computeN());
249 assertEquals(0, onCompletionN());
250 assertEquals(0, onExceptionalCompletionN());
251 assertEquals(0, setRawResultN());
252 checkNotDone(this);
253 }
254 void checkCompletes(Object rawResult) {
255 checkIncomplete();
256 int pendingCount = getPendingCount();
257 complete(rawResult);
258 assertEquals(pendingCount, getPendingCount());
259 assertEquals(0, computeN());
260 assertEquals(1, onCompletionN());
261 assertEquals(0, onExceptionalCompletionN());
262 assertEquals(1, setRawResultN());
263 assertSame(rawResult, this.rawResult.get());
264 checkCompletedNormally(this);
265 }
266 void checkCompletesExceptionally(Throwable ex) {
267 checkIncomplete();
268 completeExceptionally(ex);
269 checkCompletedExceptionally(ex);
270 }
271 void checkCompletedExceptionally(Throwable ex) {
272 assertEquals(0, computeN());
273 assertEquals(0, onCompletionN());
274 assertEquals(1, onExceptionalCompletionN());
275 assertEquals(0, setRawResultN());
276 assertNull(this.rawResult.get());
277 checkCompletedAbnormally(this, ex);
278 }
279 }
280
281 final class NoopCC extends CheckedCC {
282 NoopCC() { super(); }
283 NoopCC(CountedCompleter p) { super(p); }
284 NoopCC(CountedCompleter p, int initialPendingCount) {
285 super(p, initialPendingCount);
286 }
287 protected void realCompute() {}
288 }
289
290 /**
291 * A newly constructed CountedCompleter is not completed;
292 * complete() causes completion. pendingCount is ignored.
293 */
294 public void testComplete() {
295 for (Object x : new Object[] { Boolean.TRUE, null }) {
296 for (int pendingCount : new int[] { 0, 42 }) {
297 testComplete(new NoopCC(), x, pendingCount);
298 testComplete(new NoopCC(new NoopCC()), x, pendingCount);
299 }
300 }
301 }
302 void testComplete(NoopCC cc, Object x, int pendingCount) {
303 cc.setPendingCount(pendingCount);
304 cc.checkCompletes(x);
305 assertEquals(pendingCount, cc.getPendingCount());
306 }
307
308 /**
309 * completeExceptionally completes exceptionally
310 */
311 public void testCompleteExceptionally() {
312 new NoopCC()
313 .checkCompletesExceptionally(new FJException());
314 new NoopCC(new NoopCC())
315 .checkCompletesExceptionally(new FJException());
316 }
317
318 /**
319 * completeExceptionally(null) surprisingly has the same effect as
320 * completeExceptionally(new RuntimeException())
321 */
322 public void testCompleteExceptionally_null() {
323 NoopCC a = new NoopCC();
324 a.completeExceptionally(null);
325 try {
326 a.invoke();
327 shouldThrow();
328 } catch (RuntimeException success) {
329 assertSame(success.getClass(), RuntimeException.class);
330 assertNull(success.getCause());
331 a.checkCompletedExceptionally(success);
332 }
333 }
334
335 /**
336 * setPendingCount sets the reported pending count
337 */
338 public void testSetPendingCount() {
339 NoopCC a = new NoopCC();
340 assertEquals(0, a.getPendingCount());
341 int[] vals = {
342 -1, 0, 1,
343 Integer.MIN_VALUE,
344 Integer.MAX_VALUE,
345 };
346 for (int val : vals) {
347 a.setPendingCount(val);
348 assertEquals(val, a.getPendingCount());
349 }
350 }
351
352 /**
353 * addToPendingCount adds to the reported pending count
354 */
355 public void testAddToPendingCount() {
356 NoopCC a = new NoopCC();
357 assertEquals(0, a.getPendingCount());
358 a.addToPendingCount(1);
359 assertEquals(1, a.getPendingCount());
360 a.addToPendingCount(27);
361 assertEquals(28, a.getPendingCount());
362 a.addToPendingCount(-28);
363 assertEquals(0, a.getPendingCount());
364 }
365
366 /**
367 * decrementPendingCountUnlessZero decrements reported pending
368 * count unless zero
369 */
370 public void testDecrementPendingCountUnlessZero() {
371 NoopCC a = new NoopCC(null, 2);
372 assertEquals(2, a.getPendingCount());
373 assertEquals(2, a.decrementPendingCountUnlessZero());
374 assertEquals(1, a.getPendingCount());
375 assertEquals(1, a.decrementPendingCountUnlessZero());
376 assertEquals(0, a.getPendingCount());
377 assertEquals(0, a.decrementPendingCountUnlessZero());
378 assertEquals(0, a.getPendingCount());
379 a.setPendingCount(-1);
380 assertEquals(-1, a.decrementPendingCountUnlessZero());
381 assertEquals(-2, a.getPendingCount());
382 }
383
384 /**
385 * compareAndSetPendingCount compares and sets the reported
386 * pending count
387 */
388 public void testCompareAndSetPendingCount() {
389 NoopCC a = new NoopCC();
390 assertEquals(0, a.getPendingCount());
391 assertTrue(a.compareAndSetPendingCount(0, 1));
392 assertEquals(1, a.getPendingCount());
393 assertTrue(a.compareAndSetPendingCount(1, 2));
394 assertEquals(2, a.getPendingCount());
395 assertFalse(a.compareAndSetPendingCount(1, 3));
396 assertEquals(2, a.getPendingCount());
397 }
398
399 /**
400 * getCompleter returns parent or null if at root
401 */
402 public void testGetCompleter() {
403 NoopCC a = new NoopCC();
404 assertNull(a.getCompleter());
405 CountedCompleter b = new NoopCC(a);
406 assertSame(a, b.getCompleter());
407 CountedCompleter c = new NoopCC(b);
408 assertSame(b, c.getCompleter());
409 }
410
411 /**
412 * getRoot returns self if no parent, else parent's root
413 */
414 public void testGetRoot() {
415 NoopCC a = new NoopCC();
416 NoopCC b = new NoopCC(a);
417 NoopCC c = new NoopCC(b);
418 assertSame(a, a.getRoot());
419 assertSame(a, b.getRoot());
420 assertSame(a, c.getRoot());
421 }
422
423 /**
424 * tryComplete decrements pending count unless zero, in which case
425 * causes completion
426 */
427 public void testTryComplete() {
428 NoopCC a = new NoopCC();
429 assertEquals(0, a.getPendingCount());
430 int n = 3;
431 a.setPendingCount(n);
432 for (; n > 0; n--) {
433 assertEquals(n, a.getPendingCount());
434 a.tryComplete();
435 a.checkIncomplete();
436 assertEquals(n - 1, a.getPendingCount());
437 }
438 a.tryComplete();
439 assertEquals(0, a.computeN());
440 assertEquals(1, a.onCompletionN());
441 assertEquals(0, a.onExceptionalCompletionN());
442 assertEquals(0, a.setRawResultN());
443 checkCompletedNormally(a);
444 }
445
446 /**
447 * propagateCompletion decrements pending count unless zero, in
448 * which case causes completion, without invoking onCompletion
449 */
450 public void testPropagateCompletion() {
451 NoopCC a = new NoopCC();
452 assertEquals(0, a.getPendingCount());
453 int n = 3;
454 a.setPendingCount(n);
455 for (; n > 0; n--) {
456 assertEquals(n, a.getPendingCount());
457 a.propagateCompletion();
458 a.checkIncomplete();
459 assertEquals(n - 1, a.getPendingCount());
460 }
461 a.propagateCompletion();
462 assertEquals(0, a.computeN());
463 assertEquals(0, a.onCompletionN());
464 assertEquals(0, a.onExceptionalCompletionN());
465 assertEquals(0, a.setRawResultN());
466 checkCompletedNormally(a);
467 }
468
469 /**
470 * firstComplete returns this if pending count is zero else null
471 */
472 public void testFirstComplete() {
473 NoopCC a = new NoopCC();
474 a.setPendingCount(1);
475 assertNull(a.firstComplete());
476 a.checkIncomplete();
477 assertSame(a, a.firstComplete());
478 a.checkIncomplete();
479 }
480
481 /**
482 * firstComplete.nextComplete returns parent if pending count is
483 * zero else null
484 */
485 public void testNextComplete() {
486 NoopCC a = new NoopCC();
487 NoopCC b = new NoopCC(a);
488 a.setPendingCount(1);
489 b.setPendingCount(1);
490 assertNull(b.firstComplete());
491 assertSame(b, b.firstComplete());
492 assertNull(b.nextComplete());
493 a.checkIncomplete();
494 b.checkIncomplete();
495 assertSame(a, b.nextComplete());
496 assertSame(a, b.nextComplete());
497 a.checkIncomplete();
498 b.checkIncomplete();
499 assertNull(a.nextComplete());
500 b.checkIncomplete();
501 checkCompletedNormally(a);
502 }
503
504 /**
505 * quietlyCompleteRoot completes root task and only root task
506 */
507 public void testQuietlyCompleteRoot() {
508 NoopCC a = new NoopCC();
509 NoopCC b = new NoopCC(a);
510 NoopCC c = new NoopCC(b);
511 a.setPendingCount(1);
512 b.setPendingCount(1);
513 c.setPendingCount(1);
514 c.quietlyCompleteRoot();
515 assertTrue(a.isDone());
516 assertFalse(b.isDone());
517 assertFalse(c.isDone());
518 }
519
520 // Invocation tests use some interdependent task classes
521 // to better test propagation etc
522
523 /**
524 * Version of Fibonacci with different classes for left vs right forks
525 */
526 abstract class CCF extends CheckedCC {
527 int number;
528 int rnumber;
529
530 public CCF(CountedCompleter parent, int n) {
531 super(parent, 1);
532 this.number = n;
533 }
534
535 protected final void realCompute() {
536 CCF f = this;
537 int n = number;
538 while (n >= 2) {
539 new RCCF(f, n - 2).fork();
540 f = new LCCF(f, --n);
541 }
542 f.complete(null);
543 }
544 }
545
546 final class LCCF extends CCF {
547 public LCCF(int n) { this(null, n); }
548 public LCCF(CountedCompleter parent, int n) {
549 super(parent, n);
550 }
551 public final void onCompletion(CountedCompleter caller) {
552 super.onCompletion(caller);
553 CCF p = (CCF)getCompleter();
554 int n = number + rnumber;
555 if (p != null)
556 p.number = n;
557 else
558 number = n;
559 }
560 }
561 final class RCCF extends CCF {
562 public RCCF(CountedCompleter parent, int n) {
563 super(parent, n);
564 }
565 public final void onCompletion(CountedCompleter caller) {
566 super.onCompletion(caller);
567 CCF p = (CCF)getCompleter();
568 int n = number + rnumber;
569 if (p != null)
570 p.rnumber = n;
571 else
572 number = n;
573 }
574 }
575
576 // Version of CCF with forced failure in left completions
577 abstract class FailingCCF extends CheckedCC {
578 int number;
579 int rnumber;
580
581 public FailingCCF(CountedCompleter parent, int n) {
582 super(parent, 1);
583 this.number = n;
584 }
585
586 protected final void realCompute() {
587 FailingCCF f = this;
588 int n = number;
589 while (n >= 2) {
590 new RFCCF(f, n - 2).fork();
591 f = new LFCCF(f, --n);
592 }
593 f.complete(null);
594 }
595 }
596
597 final class LFCCF extends FailingCCF {
598 public LFCCF(int n) { this(null, n); }
599 public LFCCF(CountedCompleter parent, int n) {
600 super(parent, n);
601 }
602 public final void onCompletion(CountedCompleter caller) {
603 super.onCompletion(caller);
604 FailingCCF p = (FailingCCF)getCompleter();
605 int n = number + rnumber;
606 if (p != null)
607 p.number = n;
608 else
609 number = n;
610 }
611 }
612 final class RFCCF extends FailingCCF {
613 public RFCCF(CountedCompleter parent, int n) {
614 super(parent, n);
615 }
616 public final void onCompletion(CountedCompleter caller) {
617 super.onCompletion(caller);
618 completeExceptionally(new FJException());
619 }
620 }
621
622 /**
623 * invoke returns when task completes normally.
624 * isCompletedAbnormally and isCancelled return false for normally
625 * completed tasks; getRawResult returns null.
626 */
627 public void testInvoke() {
628 ForkJoinTask a = new CheckedRecursiveAction() {
629 protected void realCompute() {
630 CCF f = new LCCF(8);
631 assertNull(f.invoke());
632 assertEquals(21, f.number);
633 checkCompletedNormally(f);
634 }};
635 testInvokeOnPool(mainPool(), a);
636 }
637
638 /**
639 * quietlyInvoke task returns when task completes normally.
640 * isCompletedAbnormally and isCancelled return false for normally
641 * completed tasks
642 */
643 public void testQuietlyInvoke() {
644 ForkJoinTask a = new CheckedRecursiveAction() {
645 protected void realCompute() {
646 CCF f = new LCCF(8);
647 f.quietlyInvoke();
648 assertEquals(21, f.number);
649 checkCompletedNormally(f);
650 }};
651 testInvokeOnPool(mainPool(), a);
652 }
653
654 /**
655 * join of a forked task returns when task completes
656 */
657 public void testForkJoin() {
658 ForkJoinTask a = new CheckedRecursiveAction() {
659 protected void realCompute() {
660 CCF f = new LCCF(8);
661 assertSame(f, f.fork());
662 assertNull(f.join());
663 assertEquals(21, f.number);
664 checkCompletedNormally(f);
665 }};
666 testInvokeOnPool(mainPool(), a);
667 }
668
669 /**
670 * get of a forked task returns when task completes
671 */
672 public void testForkGet() {
673 ForkJoinTask a = new CheckedRecursiveAction() {
674 protected void realCompute() throws Exception {
675 CCF f = new LCCF(8);
676 assertSame(f, f.fork());
677 assertNull(f.get());
678 assertEquals(21, f.number);
679 checkCompletedNormally(f);
680 }};
681 testInvokeOnPool(mainPool(), a);
682 }
683
684 /**
685 * timed get of a forked task returns when task completes
686 */
687 public void testForkTimedGet() {
688 ForkJoinTask a = new CheckedRecursiveAction() {
689 protected void realCompute() throws Exception {
690 CCF f = new LCCF(8);
691 assertSame(f, f.fork());
692 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
693 assertEquals(21, f.number);
694 checkCompletedNormally(f);
695 }};
696 testInvokeOnPool(mainPool(), a);
697 }
698
699 /**
700 * timed get with null time unit throws NPE
701 */
702 public void testForkTimedGetNPE() {
703 ForkJoinTask a = new CheckedRecursiveAction() {
704 protected void realCompute() throws Exception {
705 CCF f = new LCCF(8);
706 assertSame(f, f.fork());
707 try {
708 f.get(5L, null);
709 shouldThrow();
710 } catch (NullPointerException success) {}
711 }};
712 testInvokeOnPool(mainPool(), a);
713 }
714
715 /**
716 * quietlyJoin of a forked task returns when task completes
717 */
718 public void testForkQuietlyJoin() {
719 ForkJoinTask a = new CheckedRecursiveAction() {
720 protected void realCompute() {
721 CCF f = new LCCF(8);
722 assertSame(f, f.fork());
723 f.quietlyJoin();
724 assertEquals(21, f.number);
725 checkCompletedNormally(f);
726 }};
727 testInvokeOnPool(mainPool(), a);
728 }
729
730 /**
731 * helpQuiesce returns when tasks are complete.
732 * getQueuedTaskCount returns 0 when quiescent
733 */
734 public void testForkHelpQuiesce() {
735 ForkJoinTask a = new CheckedRecursiveAction() {
736 protected void realCompute() {
737 CCF f = new LCCF(8);
738 assertSame(f, f.fork());
739 helpQuiesce();
740 assertEquals(21, f.number);
741 assertEquals(0, getQueuedTaskCount());
742 checkCompletedNormally(f);
743 }};
744 testInvokeOnPool(mainPool(), a);
745 }
746
747 /**
748 * invoke task throws exception when task completes abnormally
749 */
750 public void testAbnormalInvoke() {
751 ForkJoinTask a = new CheckedRecursiveAction() {
752 protected void realCompute() {
753 FailingCCF f = new LFCCF(8);
754 try {
755 f.invoke();
756 shouldThrow();
757 } catch (FJException success) {
758 checkCompletedAbnormally(f, success);
759 }
760 }};
761 testInvokeOnPool(mainPool(), a);
762 }
763
764 /**
765 * quietlyInvoke task returns when task completes abnormally
766 */
767 public void testAbnormalQuietlyInvoke() {
768 ForkJoinTask a = new CheckedRecursiveAction() {
769 protected void realCompute() {
770 FailingCCF f = new LFCCF(8);
771 f.quietlyInvoke();
772 assertTrue(f.getException() instanceof FJException);
773 checkCompletedAbnormally(f, f.getException());
774 }};
775 testInvokeOnPool(mainPool(), a);
776 }
777
778 /**
779 * join of a forked task throws exception when task completes abnormally
780 */
781 public void testAbnormalForkJoin() {
782 ForkJoinTask a = new CheckedRecursiveAction() {
783 protected void realCompute() {
784 FailingCCF f = new LFCCF(8);
785 assertSame(f, f.fork());
786 try {
787 f.join();
788 shouldThrow();
789 } catch (FJException success) {
790 checkCompletedAbnormally(f, success);
791 }
792 }};
793 testInvokeOnPool(mainPool(), a);
794 }
795
796 /**
797 * get of a forked task throws exception when task completes abnormally
798 */
799 public void testAbnormalForkGet() {
800 ForkJoinTask a = new CheckedRecursiveAction() {
801 protected void realCompute() throws Exception {
802 FailingCCF f = new LFCCF(8);
803 assertSame(f, f.fork());
804 try {
805 f.get();
806 shouldThrow();
807 } catch (ExecutionException success) {
808 Throwable cause = success.getCause();
809 assertTrue(cause instanceof FJException);
810 checkCompletedAbnormally(f, cause);
811 }
812 }};
813 testInvokeOnPool(mainPool(), a);
814 }
815
816 /**
817 * timed get of a forked task throws exception when task completes abnormally
818 */
819 public void testAbnormalForkTimedGet() {
820 ForkJoinTask a = new CheckedRecursiveAction() {
821 protected void realCompute() throws Exception {
822 FailingCCF f = new LFCCF(8);
823 assertSame(f, f.fork());
824 try {
825 f.get(LONG_DELAY_MS, MILLISECONDS);
826 shouldThrow();
827 } catch (ExecutionException success) {
828 Throwable cause = success.getCause();
829 assertTrue(cause instanceof FJException);
830 checkCompletedAbnormally(f, cause);
831 }
832 }};
833 testInvokeOnPool(mainPool(), a);
834 }
835
836 /**
837 * quietlyJoin of a forked task returns when task completes abnormally
838 */
839 public void testAbnormalForkQuietlyJoin() {
840 ForkJoinTask a = new CheckedRecursiveAction() {
841 protected void realCompute() {
842 FailingCCF f = new LFCCF(8);
843 assertSame(f, f.fork());
844 f.quietlyJoin();
845 assertTrue(f.getException() instanceof FJException);
846 checkCompletedAbnormally(f, f.getException());
847 }};
848 testInvokeOnPool(mainPool(), a);
849 }
850
851 /**
852 * invoke task throws exception when task cancelled
853 */
854 public void testCancelledInvoke() {
855 ForkJoinTask a = new CheckedRecursiveAction() {
856 protected void realCompute() {
857 CCF f = new LCCF(8);
858 assertTrue(f.cancel(true));
859 try {
860 f.invoke();
861 shouldThrow();
862 } catch (CancellationException success) {
863 checkCancelled(f);
864 }
865 }};
866 testInvokeOnPool(mainPool(), a);
867 }
868
869 /**
870 * join of a forked task throws exception when task cancelled
871 */
872 public void testCancelledForkJoin() {
873 ForkJoinTask a = new CheckedRecursiveAction() {
874 protected void realCompute() {
875 CCF f = new LCCF(8);
876 assertTrue(f.cancel(true));
877 assertSame(f, f.fork());
878 try {
879 f.join();
880 shouldThrow();
881 } catch (CancellationException success) {
882 checkCancelled(f);
883 }
884 }};
885 testInvokeOnPool(mainPool(), a);
886 }
887
888 /**
889 * get of a forked task throws exception when task cancelled
890 */
891 public void testCancelledForkGet() {
892 ForkJoinTask a = new CheckedRecursiveAction() {
893 protected void realCompute() throws Exception {
894 CCF f = new LCCF(8);
895 assertTrue(f.cancel(true));
896 assertSame(f, f.fork());
897 try {
898 f.get();
899 shouldThrow();
900 } catch (CancellationException success) {
901 checkCancelled(f);
902 }
903 }};
904 testInvokeOnPool(mainPool(), a);
905 }
906
907 /**
908 * timed get of a forked task throws exception when task cancelled
909 */
910 public void testCancelledForkTimedGet() throws Exception {
911 ForkJoinTask a = new CheckedRecursiveAction() {
912 protected void realCompute() throws Exception {
913 CCF f = new LCCF(8);
914 assertTrue(f.cancel(true));
915 assertSame(f, f.fork());
916 try {
917 f.get(LONG_DELAY_MS, MILLISECONDS);
918 shouldThrow();
919 } catch (CancellationException success) {
920 checkCancelled(f);
921 }
922 }};
923 testInvokeOnPool(mainPool(), a);
924 }
925
926 /**
927 * quietlyJoin of a forked task returns when task cancelled
928 */
929 public void testCancelledForkQuietlyJoin() {
930 ForkJoinTask a = new CheckedRecursiveAction() {
931 protected void realCompute() {
932 CCF f = new LCCF(8);
933 assertTrue(f.cancel(true));
934 assertSame(f, f.fork());
935 f.quietlyJoin();
936 checkCancelled(f);
937 }};
938 testInvokeOnPool(mainPool(), a);
939 }
940
941 /**
942 * getPool of executing task returns its pool
943 */
944 public void testGetPool() {
945 final ForkJoinPool mainPool = mainPool();
946 ForkJoinTask a = new CheckedRecursiveAction() {
947 protected void realCompute() {
948 assertSame(mainPool, getPool());
949 }};
950 testInvokeOnPool(mainPool, a);
951 }
952
953 /**
954 * getPool of non-FJ task returns null
955 */
956 public void testGetPool2() {
957 ForkJoinTask a = new CheckedRecursiveAction() {
958 protected void realCompute() {
959 assertNull(getPool());
960 }};
961 assertNull(a.invoke());
962 }
963
964 /**
965 * inForkJoinPool of executing task returns true
966 */
967 public void testInForkJoinPool() {
968 ForkJoinTask a = new CheckedRecursiveAction() {
969 protected void realCompute() {
970 assertTrue(inForkJoinPool());
971 }};
972 testInvokeOnPool(mainPool(), a);
973 }
974
975 /**
976 * inForkJoinPool of non-FJ task returns false
977 */
978 public void testInForkJoinPool2() {
979 ForkJoinTask a = new CheckedRecursiveAction() {
980 protected void realCompute() {
981 assertFalse(inForkJoinPool());
982 }};
983 assertNull(a.invoke());
984 }
985
986 /**
987 * setRawResult(null) succeeds
988 */
989 public void testSetRawResult() {
990 ForkJoinTask a = new CheckedRecursiveAction() {
991 protected void realCompute() {
992 setRawResult(null);
993 assertNull(getRawResult());
994 }};
995 assertNull(a.invoke());
996 }
997
998 /**
999 * invoke task throws exception after invoking completeExceptionally
1000 */
1001 public void testCompleteExceptionally2() {
1002 ForkJoinTask a = new CheckedRecursiveAction() {
1003 protected void realCompute() {
1004 CCF n = new LCCF(8);
1005 CCF f = new LCCF(n, 8);
1006 FJException ex = new FJException();
1007 f.completeExceptionally(ex);
1008 f.checkCompletedExceptionally(ex);
1009 n.checkCompletedExceptionally(ex);
1010 }};
1011 testInvokeOnPool(mainPool(), a);
1012 }
1013
1014 /**
1015 * invokeAll(t1, t2) invokes all task arguments
1016 */
1017 public void testInvokeAll2() {
1018 ForkJoinTask a = new CheckedRecursiveAction() {
1019 protected void realCompute() {
1020 CCF f = new LCCF(8);
1021 CCF g = new LCCF(9);
1022 invokeAll(f, g);
1023 assertEquals(21, f.number);
1024 assertEquals(34, g.number);
1025 checkCompletedNormally(f);
1026 checkCompletedNormally(g);
1027 }};
1028 testInvokeOnPool(mainPool(), a);
1029 }
1030
1031 /**
1032 * invokeAll(tasks) with 1 argument invokes task
1033 */
1034 public void testInvokeAll1() {
1035 ForkJoinTask a = new CheckedRecursiveAction() {
1036 protected void realCompute() {
1037 CCF f = new LCCF(8);
1038 invokeAll(f);
1039 checkCompletedNormally(f);
1040 assertEquals(21, f.number);
1041 }};
1042 testInvokeOnPool(mainPool(), a);
1043 }
1044
1045 /**
1046 * invokeAll(tasks) with > 2 argument invokes tasks
1047 */
1048 public void testInvokeAll3() {
1049 ForkJoinTask a = new CheckedRecursiveAction() {
1050 protected void realCompute() {
1051 CCF f = new LCCF(8);
1052 CCF g = new LCCF(9);
1053 CCF h = new LCCF(7);
1054 invokeAll(f, g, h);
1055 assertEquals(21, f.number);
1056 assertEquals(34, g.number);
1057 assertEquals(13, h.number);
1058 checkCompletedNormally(f);
1059 checkCompletedNormally(g);
1060 checkCompletedNormally(h);
1061 }};
1062 testInvokeOnPool(mainPool(), a);
1063 }
1064
1065 /**
1066 * invokeAll(collection) invokes all tasks in the collection
1067 */
1068 public void testInvokeAllCollection() {
1069 ForkJoinTask a = new CheckedRecursiveAction() {
1070 protected void realCompute() {
1071 CCF f = new LCCF(8);
1072 CCF g = new LCCF(9);
1073 CCF h = new LCCF(7);
1074 HashSet set = new HashSet();
1075 set.add(f);
1076 set.add(g);
1077 set.add(h);
1078 invokeAll(set);
1079 assertEquals(21, f.number);
1080 assertEquals(34, g.number);
1081 assertEquals(13, h.number);
1082 checkCompletedNormally(f);
1083 checkCompletedNormally(g);
1084 checkCompletedNormally(h);
1085 }};
1086 testInvokeOnPool(mainPool(), a);
1087 }
1088
1089 /**
1090 * invokeAll(tasks) with any null task throws NPE
1091 */
1092 public void testInvokeAllNPE() {
1093 ForkJoinTask a = new CheckedRecursiveAction() {
1094 protected void realCompute() {
1095 CCF f = new LCCF(8);
1096 CCF g = new LCCF(9);
1097 CCF h = null;
1098 try {
1099 invokeAll(f, g, h);
1100 shouldThrow();
1101 } catch (NullPointerException success) {}
1102 }};
1103 testInvokeOnPool(mainPool(), a);
1104 }
1105
1106 /**
1107 * invokeAll(t1, t2) throw exception if any task does
1108 */
1109 public void testAbnormalInvokeAll2() {
1110 ForkJoinTask a = new CheckedRecursiveAction() {
1111 protected void realCompute() {
1112 CCF f = new LCCF(8);
1113 FailingCCF g = new LFCCF(9);
1114 try {
1115 invokeAll(f, g);
1116 shouldThrow();
1117 } catch (FJException success) {
1118 checkCompletedAbnormally(g, success);
1119 }
1120 }};
1121 testInvokeOnPool(mainPool(), a);
1122 }
1123
1124 /**
1125 * invokeAll(tasks) with 1 argument throws exception if task does
1126 */
1127 public void testAbnormalInvokeAll1() {
1128 ForkJoinTask a = new CheckedRecursiveAction() {
1129 protected void realCompute() {
1130 FailingCCF g = new LFCCF(9);
1131 try {
1132 invokeAll(g);
1133 shouldThrow();
1134 } catch (FJException success) {
1135 checkCompletedAbnormally(g, success);
1136 }
1137 }};
1138 testInvokeOnPool(mainPool(), a);
1139 }
1140
1141 /**
1142 * invokeAll(tasks) with > 2 argument throws exception if any task does
1143 */
1144 public void testAbnormalInvokeAll3() {
1145 ForkJoinTask a = new CheckedRecursiveAction() {
1146 protected void realCompute() {
1147 CCF f = new LCCF(8);
1148 FailingCCF g = new LFCCF(9);
1149 CCF h = new LCCF(7);
1150 try {
1151 invokeAll(f, g, h);
1152 shouldThrow();
1153 } catch (FJException success) {
1154 checkCompletedAbnormally(g, success);
1155 }
1156 }};
1157 testInvokeOnPool(mainPool(), a);
1158 }
1159
1160 /**
1161 * invokeAll(collection) throws exception if any task does
1162 */
1163 public void testAbnormalInvokeAllCollection() {
1164 ForkJoinTask a = new CheckedRecursiveAction() {
1165 protected void realCompute() {
1166 FailingCCF f = new LFCCF(8);
1167 CCF g = new LCCF(9);
1168 CCF h = new LCCF(7);
1169 HashSet set = new HashSet();
1170 set.add(f);
1171 set.add(g);
1172 set.add(h);
1173 try {
1174 invokeAll(set);
1175 shouldThrow();
1176 } catch (FJException success) {
1177 checkCompletedAbnormally(f, success);
1178 }
1179 }};
1180 testInvokeOnPool(mainPool(), a);
1181 }
1182
1183 /**
1184 * tryUnfork returns true for most recent unexecuted task,
1185 * and suppresses execution
1186 */
1187 public void testTryUnfork() {
1188 ForkJoinTask a = new CheckedRecursiveAction() {
1189 protected void realCompute() {
1190 CCF g = new LCCF(9);
1191 assertSame(g, g.fork());
1192 CCF f = new LCCF(8);
1193 assertSame(f, f.fork());
1194 assertTrue(f.tryUnfork());
1195 helpQuiesce();
1196 checkNotDone(f);
1197 checkCompletedNormally(g);
1198 }};
1199 testInvokeOnPool(singletonPool(), a);
1200 }
1201
1202 /**
1203 * getSurplusQueuedTaskCount returns > 0 when
1204 * there are more tasks than threads
1205 */
1206 public void testGetSurplusQueuedTaskCount() {
1207 ForkJoinTask a = new CheckedRecursiveAction() {
1208 protected void realCompute() {
1209 CCF h = new LCCF(7);
1210 assertSame(h, h.fork());
1211 CCF g = new LCCF(9);
1212 assertSame(g, g.fork());
1213 CCF f = new LCCF(8);
1214 assertSame(f, f.fork());
1215 assertTrue(getSurplusQueuedTaskCount() > 0);
1216 helpQuiesce();
1217 assertEquals(0, getSurplusQueuedTaskCount());
1218 checkCompletedNormally(f);
1219 checkCompletedNormally(g);
1220 checkCompletedNormally(h);
1221 }};
1222 testInvokeOnPool(singletonPool(), a);
1223 }
1224
1225 /**
1226 * peekNextLocalTask returns most recent unexecuted task.
1227 */
1228 public void testPeekNextLocalTask() {
1229 ForkJoinTask a = new CheckedRecursiveAction() {
1230 protected void realCompute() {
1231 CCF g = new LCCF(9);
1232 assertSame(g, g.fork());
1233 CCF f = new LCCF(8);
1234 assertSame(f, f.fork());
1235 assertSame(f, peekNextLocalTask());
1236 assertNull(f.join());
1237 checkCompletedNormally(f);
1238 helpQuiesce();
1239 checkCompletedNormally(g);
1240 }};
1241 testInvokeOnPool(singletonPool(), a);
1242 }
1243
1244 /**
1245 * pollNextLocalTask returns most recent unexecuted task without
1246 * executing it
1247 */
1248 public void testPollNextLocalTask() {
1249 ForkJoinTask a = new CheckedRecursiveAction() {
1250 protected void realCompute() {
1251 CCF g = new LCCF(9);
1252 assertSame(g, g.fork());
1253 CCF f = new LCCF(8);
1254 assertSame(f, f.fork());
1255 assertSame(f, pollNextLocalTask());
1256 helpQuiesce();
1257 checkNotDone(f);
1258 assertEquals(34, g.number);
1259 checkCompletedNormally(g);
1260 }};
1261 testInvokeOnPool(singletonPool(), a);
1262 }
1263
1264 /**
1265 * pollTask returns an unexecuted task without executing it
1266 */
1267 public void testPollTask() {
1268 ForkJoinTask a = new CheckedRecursiveAction() {
1269 protected void realCompute() {
1270 CCF g = new LCCF(9);
1271 assertSame(g, g.fork());
1272 CCF f = new LCCF(8);
1273 assertSame(f, f.fork());
1274 assertSame(f, pollTask());
1275 helpQuiesce();
1276 checkNotDone(f);
1277 checkCompletedNormally(g);
1278 }};
1279 testInvokeOnPool(singletonPool(), a);
1280 }
1281
1282 /**
1283 * peekNextLocalTask returns least recent unexecuted task in async mode
1284 */
1285 public void testPeekNextLocalTaskAsync() {
1286 ForkJoinTask a = new CheckedRecursiveAction() {
1287 protected void realCompute() {
1288 CCF g = new LCCF(9);
1289 assertSame(g, g.fork());
1290 CCF f = new LCCF(8);
1291 assertSame(f, f.fork());
1292 assertSame(g, peekNextLocalTask());
1293 assertNull(f.join());
1294 helpQuiesce();
1295 checkCompletedNormally(f);
1296 assertEquals(34, g.number);
1297 checkCompletedNormally(g);
1298 }};
1299 testInvokeOnPool(asyncSingletonPool(), a);
1300 }
1301
1302 /**
1303 * pollNextLocalTask returns least recent unexecuted task without
1304 * executing it, in async mode
1305 */
1306 public void testPollNextLocalTaskAsync() {
1307 ForkJoinTask a = new CheckedRecursiveAction() {
1308 protected void realCompute() {
1309 CCF g = new LCCF(9);
1310 assertSame(g, g.fork());
1311 CCF f = new LCCF(8);
1312 assertSame(f, f.fork());
1313 assertSame(g, pollNextLocalTask());
1314 helpQuiesce();
1315 assertEquals(21, f.number);
1316 checkCompletedNormally(f);
1317 checkNotDone(g);
1318 }};
1319 testInvokeOnPool(asyncSingletonPool(), a);
1320 }
1321
1322 /**
1323 * pollTask returns an unexecuted task without executing it, in
1324 * async mode
1325 */
1326 public void testPollTaskAsync() {
1327 ForkJoinTask a = new CheckedRecursiveAction() {
1328 protected void realCompute() {
1329 CCF g = new LCCF(9);
1330 assertSame(g, g.fork());
1331 CCF f = new LCCF(8);
1332 assertSame(f, f.fork());
1333 assertSame(g, pollTask());
1334 helpQuiesce();
1335 assertEquals(21, f.number);
1336 checkCompletedNormally(f);
1337 checkNotDone(g);
1338 }};
1339 testInvokeOnPool(asyncSingletonPool(), a);
1340 }
1341
1342 // versions for singleton pools
1343
1344 /**
1345 * invoke returns when task completes normally.
1346 * isCompletedAbnormally and isCancelled return false for normally
1347 * completed tasks; getRawResult returns null.
1348 */
1349 public void testInvokeSingleton() {
1350 ForkJoinTask a = new CheckedRecursiveAction() {
1351 protected void realCompute() {
1352 CCF f = new LCCF(8);
1353 assertNull(f.invoke());
1354 assertEquals(21, f.number);
1355 checkCompletedNormally(f);
1356 }};
1357 testInvokeOnPool(singletonPool(), a);
1358 }
1359
1360 /**
1361 * quietlyInvoke task returns when task completes normally.
1362 * isCompletedAbnormally and isCancelled return false for normally
1363 * completed tasks
1364 */
1365 public void testQuietlyInvokeSingleton() {
1366 ForkJoinTask a = new CheckedRecursiveAction() {
1367 protected void realCompute() {
1368 CCF f = new LCCF(8);
1369 f.quietlyInvoke();
1370 assertEquals(21, f.number);
1371 checkCompletedNormally(f);
1372 }};
1373 testInvokeOnPool(singletonPool(), a);
1374 }
1375
1376 /**
1377 * join of a forked task returns when task completes
1378 */
1379 public void testForkJoinSingleton() {
1380 ForkJoinTask a = new CheckedRecursiveAction() {
1381 protected void realCompute() {
1382 CCF f = new LCCF(8);
1383 assertSame(f, f.fork());
1384 assertNull(f.join());
1385 assertEquals(21, f.number);
1386 checkCompletedNormally(f);
1387 }};
1388 testInvokeOnPool(singletonPool(), a);
1389 }
1390
1391 /**
1392 * get of a forked task returns when task completes
1393 */
1394 public void testForkGetSingleton() {
1395 ForkJoinTask a = new CheckedRecursiveAction() {
1396 protected void realCompute() throws Exception {
1397 CCF f = new LCCF(8);
1398 assertSame(f, f.fork());
1399 assertNull(f.get());
1400 assertEquals(21, f.number);
1401 checkCompletedNormally(f);
1402 }};
1403 testInvokeOnPool(singletonPool(), a);
1404 }
1405
1406 /**
1407 * timed get of a forked task returns when task completes
1408 */
1409 public void testForkTimedGetSingleton() {
1410 ForkJoinTask a = new CheckedRecursiveAction() {
1411 protected void realCompute() throws Exception {
1412 CCF f = new LCCF(8);
1413 assertSame(f, f.fork());
1414 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
1415 assertEquals(21, f.number);
1416 checkCompletedNormally(f);
1417 }};
1418 testInvokeOnPool(singletonPool(), a);
1419 }
1420
1421 /**
1422 * timed get with null time unit throws NPE
1423 */
1424 public void testForkTimedGetNPESingleton() {
1425 ForkJoinTask a = new CheckedRecursiveAction() {
1426 protected void realCompute() throws Exception {
1427 CCF f = new LCCF(8);
1428 assertSame(f, f.fork());
1429 try {
1430 f.get(5L, null);
1431 shouldThrow();
1432 } catch (NullPointerException success) {}
1433 }};
1434 testInvokeOnPool(singletonPool(), a);
1435 }
1436
1437 /**
1438 * quietlyJoin of a forked task returns when task completes
1439 */
1440 public void testForkQuietlyJoinSingleton() {
1441 ForkJoinTask a = new CheckedRecursiveAction() {
1442 protected void realCompute() {
1443 CCF f = new LCCF(8);
1444 assertSame(f, f.fork());
1445 f.quietlyJoin();
1446 assertEquals(21, f.number);
1447 checkCompletedNormally(f);
1448 }};
1449 testInvokeOnPool(singletonPool(), a);
1450 }
1451
1452 /**
1453 * helpQuiesce returns when tasks are complete.
1454 * getQueuedTaskCount returns 0 when quiescent
1455 */
1456 public void testForkHelpQuiesceSingleton() {
1457 ForkJoinTask a = new CheckedRecursiveAction() {
1458 protected void realCompute() {
1459 CCF f = new LCCF(8);
1460 assertSame(f, f.fork());
1461 helpQuiesce();
1462 assertEquals(0, getQueuedTaskCount());
1463 assertEquals(21, f.number);
1464 checkCompletedNormally(f);
1465 }};
1466 testInvokeOnPool(singletonPool(), a);
1467 }
1468
1469 /**
1470 * invoke task throws exception when task completes abnormally
1471 */
1472 public void testAbnormalInvokeSingleton() {
1473 ForkJoinTask a = new CheckedRecursiveAction() {
1474 protected void realCompute() {
1475 FailingCCF f = new LFCCF(8);
1476 try {
1477 f.invoke();
1478 shouldThrow();
1479 } catch (FJException success) {
1480 checkCompletedAbnormally(f, success);
1481 }
1482 }};
1483 testInvokeOnPool(singletonPool(), a);
1484 }
1485
1486 /**
1487 * quietlyInvoke task returns when task completes abnormally
1488 */
1489 public void testAbnormalQuietlyInvokeSingleton() {
1490 ForkJoinTask a = new CheckedRecursiveAction() {
1491 protected void realCompute() {
1492 FailingCCF f = new LFCCF(8);
1493 f.quietlyInvoke();
1494 assertTrue(f.getException() instanceof FJException);
1495 checkCompletedAbnormally(f, f.getException());
1496 }};
1497 testInvokeOnPool(singletonPool(), a);
1498 }
1499
1500 /**
1501 * join of a forked task throws exception when task completes abnormally
1502 */
1503 public void testAbnormalForkJoinSingleton() {
1504 ForkJoinTask a = new CheckedRecursiveAction() {
1505 protected void realCompute() {
1506 FailingCCF f = new LFCCF(8);
1507 assertSame(f, f.fork());
1508 try {
1509 f.join();
1510 shouldThrow();
1511 } catch (FJException success) {
1512 checkCompletedAbnormally(f, success);
1513 }
1514 }};
1515 testInvokeOnPool(singletonPool(), a);
1516 }
1517
1518 /**
1519 * get of a forked task throws exception when task completes abnormally
1520 */
1521 public void testAbnormalForkGetSingleton() {
1522 ForkJoinTask a = new CheckedRecursiveAction() {
1523 protected void realCompute() throws Exception {
1524 FailingCCF f = new LFCCF(8);
1525 assertSame(f, f.fork());
1526 try {
1527 f.get();
1528 shouldThrow();
1529 } catch (ExecutionException success) {
1530 Throwable cause = success.getCause();
1531 assertTrue(cause instanceof FJException);
1532 checkCompletedAbnormally(f, cause);
1533 }
1534 }};
1535 testInvokeOnPool(singletonPool(), a);
1536 }
1537
1538 /**
1539 * timed get of a forked task throws exception when task completes abnormally
1540 */
1541 public void testAbnormalForkTimedGetSingleton() {
1542 ForkJoinTask a = new CheckedRecursiveAction() {
1543 protected void realCompute() throws Exception {
1544 FailingCCF f = new LFCCF(8);
1545 assertSame(f, f.fork());
1546 try {
1547 f.get(LONG_DELAY_MS, MILLISECONDS);
1548 shouldThrow();
1549 } catch (ExecutionException success) {
1550 Throwable cause = success.getCause();
1551 assertTrue(cause instanceof FJException);
1552 checkCompletedAbnormally(f, cause);
1553 }
1554 }};
1555 testInvokeOnPool(singletonPool(), a);
1556 }
1557
1558 /**
1559 * quietlyJoin of a forked task returns when task completes abnormally
1560 */
1561 public void testAbnormalForkQuietlyJoinSingleton() {
1562 ForkJoinTask a = new CheckedRecursiveAction() {
1563 protected void realCompute() {
1564 FailingCCF f = new LFCCF(8);
1565 assertSame(f, f.fork());
1566 f.quietlyJoin();
1567 assertTrue(f.getException() instanceof FJException);
1568 checkCompletedAbnormally(f, f.getException());
1569 }};
1570 testInvokeOnPool(singletonPool(), a);
1571 }
1572
1573 /**
1574 * invoke task throws exception when task cancelled
1575 */
1576 public void testCancelledInvokeSingleton() {
1577 ForkJoinTask a = new CheckedRecursiveAction() {
1578 protected void realCompute() {
1579 CCF f = new LCCF(8);
1580 assertTrue(f.cancel(true));
1581 try {
1582 f.invoke();
1583 shouldThrow();
1584 } catch (CancellationException success) {
1585 checkCancelled(f);
1586 }
1587 }};
1588 testInvokeOnPool(singletonPool(), a);
1589 }
1590
1591 /**
1592 * join of a forked task throws exception when task cancelled
1593 */
1594 public void testCancelledForkJoinSingleton() {
1595 ForkJoinTask a = new CheckedRecursiveAction() {
1596 protected void realCompute() {
1597 CCF f = new LCCF(8);
1598 assertTrue(f.cancel(true));
1599 assertSame(f, f.fork());
1600 try {
1601 f.join();
1602 shouldThrow();
1603 } catch (CancellationException success) {
1604 checkCancelled(f);
1605 }
1606 }};
1607 testInvokeOnPool(singletonPool(), a);
1608 }
1609
1610 /**
1611 * get of a forked task throws exception when task cancelled
1612 */
1613 public void testCancelledForkGetSingleton() {
1614 ForkJoinTask a = new CheckedRecursiveAction() {
1615 protected void realCompute() throws Exception {
1616 CCF f = new LCCF(8);
1617 assertTrue(f.cancel(true));
1618 assertSame(f, f.fork());
1619 try {
1620 f.get();
1621 shouldThrow();
1622 } catch (CancellationException success) {
1623 checkCancelled(f);
1624 }
1625 }};
1626 testInvokeOnPool(singletonPool(), a);
1627 }
1628
1629 /**
1630 * timed get of a forked task throws exception when task cancelled
1631 */
1632 public void testCancelledForkTimedGetSingleton() throws Exception {
1633 ForkJoinTask a = new CheckedRecursiveAction() {
1634 protected void realCompute() throws Exception {
1635 CCF f = new LCCF(8);
1636 assertTrue(f.cancel(true));
1637 assertSame(f, f.fork());
1638 try {
1639 f.get(LONG_DELAY_MS, MILLISECONDS);
1640 shouldThrow();
1641 } catch (CancellationException success) {
1642 checkCancelled(f);
1643 }
1644 }};
1645 testInvokeOnPool(singletonPool(), a);
1646 }
1647
1648 /**
1649 * quietlyJoin of a forked task returns when task cancelled
1650 */
1651 public void testCancelledForkQuietlyJoinSingleton() {
1652 ForkJoinTask a = new CheckedRecursiveAction() {
1653 protected void realCompute() {
1654 CCF f = new LCCF(8);
1655 assertTrue(f.cancel(true));
1656 assertSame(f, f.fork());
1657 f.quietlyJoin();
1658 checkCancelled(f);
1659 }};
1660 testInvokeOnPool(singletonPool(), a);
1661 }
1662
1663 /**
1664 * invoke task throws exception after invoking completeExceptionally
1665 */
1666 public void testCompleteExceptionallySingleton() {
1667 ForkJoinTask a = new CheckedRecursiveAction() {
1668 protected void realCompute() {
1669 CCF n = new LCCF(8);
1670 CCF f = new LCCF(n, 8);
1671 FJException ex = new FJException();
1672 f.completeExceptionally(ex);
1673 f.checkCompletedExceptionally(ex);
1674 n.checkCompletedExceptionally(ex);
1675 }};
1676 testInvokeOnPool(singletonPool(), a);
1677 }
1678
1679 /**
1680 * invokeAll(t1, t2) invokes all task arguments
1681 */
1682 public void testInvokeAll2Singleton() {
1683 ForkJoinTask a = new CheckedRecursiveAction() {
1684 protected void realCompute() {
1685 CCF f = new LCCF(8);
1686 CCF g = new LCCF(9);
1687 invokeAll(f, g);
1688 assertEquals(21, f.number);
1689 assertEquals(34, g.number);
1690 checkCompletedNormally(f);
1691 checkCompletedNormally(g);
1692 }};
1693 testInvokeOnPool(singletonPool(), a);
1694 }
1695
1696 /**
1697 * invokeAll(tasks) with 1 argument invokes task
1698 */
1699 public void testInvokeAll1Singleton() {
1700 ForkJoinTask a = new CheckedRecursiveAction() {
1701 protected void realCompute() {
1702 CCF f = new LCCF(8);
1703 invokeAll(f);
1704 checkCompletedNormally(f);
1705 assertEquals(21, f.number);
1706 }};
1707 testInvokeOnPool(singletonPool(), a);
1708 }
1709
1710 /**
1711 * invokeAll(tasks) with > 2 argument invokes tasks
1712 */
1713 public void testInvokeAll3Singleton() {
1714 ForkJoinTask a = new CheckedRecursiveAction() {
1715 protected void realCompute() {
1716 CCF f = new LCCF(8);
1717 CCF g = new LCCF(9);
1718 CCF h = new LCCF(7);
1719 invokeAll(f, g, h);
1720 assertEquals(21, f.number);
1721 assertEquals(34, g.number);
1722 assertEquals(13, h.number);
1723 checkCompletedNormally(f);
1724 checkCompletedNormally(g);
1725 checkCompletedNormally(h);
1726 }};
1727 testInvokeOnPool(singletonPool(), a);
1728 }
1729
1730 /**
1731 * invokeAll(collection) invokes all tasks in the collection
1732 */
1733 public void testInvokeAllCollectionSingleton() {
1734 ForkJoinTask a = new CheckedRecursiveAction() {
1735 protected void realCompute() {
1736 CCF f = new LCCF(8);
1737 CCF g = new LCCF(9);
1738 CCF h = new LCCF(7);
1739 HashSet set = new HashSet();
1740 set.add(f);
1741 set.add(g);
1742 set.add(h);
1743 invokeAll(set);
1744 assertEquals(21, f.number);
1745 assertEquals(34, g.number);
1746 assertEquals(13, h.number);
1747 checkCompletedNormally(f);
1748 checkCompletedNormally(g);
1749 checkCompletedNormally(h);
1750 }};
1751 testInvokeOnPool(singletonPool(), a);
1752 }
1753
1754 /**
1755 * invokeAll(tasks) with any null task throws NPE
1756 */
1757 public void testInvokeAllNPESingleton() {
1758 ForkJoinTask a = new CheckedRecursiveAction() {
1759 protected void realCompute() {
1760 CCF f = new LCCF(8);
1761 CCF g = new LCCF(9);
1762 CCF h = null;
1763 try {
1764 invokeAll(f, g, h);
1765 shouldThrow();
1766 } catch (NullPointerException success) {}
1767 }};
1768 testInvokeOnPool(singletonPool(), a);
1769 }
1770
1771 /**
1772 * invokeAll(t1, t2) throw exception if any task does
1773 */
1774 public void testAbnormalInvokeAll2Singleton() {
1775 ForkJoinTask a = new CheckedRecursiveAction() {
1776 protected void realCompute() {
1777 CCF f = new LCCF(8);
1778 FailingCCF g = new LFCCF(9);
1779 try {
1780 invokeAll(f, g);
1781 shouldThrow();
1782 } catch (FJException success) {
1783 checkCompletedAbnormally(g, success);
1784 }
1785 }};
1786 testInvokeOnPool(singletonPool(), a);
1787 }
1788
1789 /**
1790 * invokeAll(tasks) with 1 argument throws exception if task does
1791 */
1792 public void testAbnormalInvokeAll1Singleton() {
1793 ForkJoinTask a = new CheckedRecursiveAction() {
1794 protected void realCompute() {
1795 FailingCCF g = new LFCCF(9);
1796 try {
1797 invokeAll(g);
1798 shouldThrow();
1799 } catch (FJException success) {
1800 checkCompletedAbnormally(g, success);
1801 }
1802 }};
1803 testInvokeOnPool(singletonPool(), a);
1804 }
1805
1806 /**
1807 * invokeAll(tasks) with > 2 argument throws exception if any task does
1808 */
1809 public void testAbnormalInvokeAll3Singleton() {
1810 ForkJoinTask a = new CheckedRecursiveAction() {
1811 protected void realCompute() {
1812 CCF f = new LCCF(8);
1813 FailingCCF g = new LFCCF(9);
1814 CCF h = new LCCF(7);
1815 try {
1816 invokeAll(f, g, h);
1817 shouldThrow();
1818 } catch (FJException success) {
1819 checkCompletedAbnormally(g, success);
1820 }
1821 }};
1822 testInvokeOnPool(singletonPool(), a);
1823 }
1824
1825 /**
1826 * invokeAll(collection) throws exception if any task does
1827 */
1828 public void testAbnormalInvokeAllCollectionSingleton() {
1829 ForkJoinTask a = new CheckedRecursiveAction() {
1830 protected void realCompute() {
1831 FailingCCF f = new LFCCF(8);
1832 CCF g = new LCCF(9);
1833 CCF h = new LCCF(7);
1834 HashSet set = new HashSet();
1835 set.add(f);
1836 set.add(g);
1837 set.add(h);
1838 try {
1839 invokeAll(set);
1840 shouldThrow();
1841 } catch (FJException success) {
1842 checkCompletedAbnormally(f, success);
1843 }
1844 }};
1845 testInvokeOnPool(singletonPool(), a);
1846 }
1847
1848 /** CountedCompleter class javadoc code sample, version 1. */
1849 public static <E> void forEach1(E[] array, Consumer<E> action) {
1850 class Task extends CountedCompleter<Void> {
1851 final int lo, hi;
1852 Task(Task parent, int lo, int hi) {
1853 super(parent); this.lo = lo; this.hi = hi;
1854 }
1855
1856 public void compute() {
1857 if (hi - lo >= 2) {
1858 int mid = (lo + hi) >>> 1;
1859 // must set pending count before fork
1860 setPendingCount(2);
1861 new Task(this, mid, hi).fork(); // right child
1862 new Task(this, lo, mid).fork(); // left child
1863 }
1864 else if (hi > lo)
1865 action.accept(array[lo]);
1866 tryComplete();
1867 }
1868 }
1869 new Task(null, 0, array.length).invoke();
1870 }
1871
1872 /** CountedCompleter class javadoc code sample, version 2. */
1873 public static <E> void forEach2(E[] array, Consumer<E> action) {
1874 class Task extends CountedCompleter<Void> {
1875 final int lo, hi;
1876 Task(Task parent, int lo, int hi) {
1877 super(parent); this.lo = lo; this.hi = hi;
1878 }
1879
1880 public void compute() {
1881 if (hi - lo >= 2) {
1882 int mid = (lo + hi) >>> 1;
1883 setPendingCount(1); // looks off by one, but correct!
1884 new Task(this, mid, hi).fork(); // right child
1885 new Task(this, lo, mid).compute(); // direct invoke
1886 } else {
1887 if (hi > lo)
1888 action.accept(array[lo]);
1889 tryComplete();
1890 }
1891 }
1892 }
1893 new Task(null, 0, array.length).invoke();
1894 }
1895
1896 /** CountedCompleter class javadoc code sample, version 3. */
1897 public static <E> void forEach3(E[] array, Consumer<E> action) {
1898 class Task extends CountedCompleter<Void> {
1899 final int lo, hi;
1900 Task(Task parent, int lo, int hi) {
1901 super(parent); this.lo = lo; this.hi = hi;
1902 }
1903
1904 public void compute() {
1905 int n = hi - lo;
1906 for (; n >= 2; n /= 2) {
1907 addToPendingCount(1);
1908 new Task(this, lo + n/2, lo + n).fork();
1909 }
1910 if (n > 0)
1911 action.accept(array[lo]);
1912 propagateCompletion();
1913 }
1914 }
1915 new Task(null, 0, array.length).invoke();
1916 }
1917
1918 /** CountedCompleter class javadoc code sample, version 4. */
1919 public static <E> void forEach4(E[] array, Consumer<E> action) {
1920 class Task extends CountedCompleter<Void> {
1921 final int lo, hi;
1922 Task(Task parent, int lo, int hi) {
1923 super(parent, 31 - Integer.numberOfLeadingZeros(hi - lo));
1924 this.lo = lo; this.hi = hi;
1925 }
1926
1927 public void compute() {
1928 for (int n = hi - lo; n >= 2; n /= 2)
1929 new Task(this, lo + n/2, lo + n).fork();
1930 action.accept(array[lo]);
1931 propagateCompletion();
1932 }
1933 }
1934 if (array.length > 0)
1935 new Task(null, 0, array.length).invoke();
1936 }
1937
1938 void testRecursiveDecomposition(
1939 BiConsumer<Integer[], Consumer<Integer>> action) {
1940 int n = ThreadLocalRandom.current().nextInt(8);
1941 Integer[] a = new Integer[n];
1942 for (int i = 0; i < n; i++) a[i] = i + 1;
1943 AtomicInteger ai = new AtomicInteger(0);
1944 action.accept(a, (x) -> ai.addAndGet(x));
1945 assertEquals(n * (n + 1) / 2, ai.get());
1946 }
1947
1948 /**
1949 * Variants of divide-by-two recursive decomposition into leaf tasks,
1950 * as described in the CountedCompleter class javadoc code samples
1951 */
1952 public void testRecursiveDecomposition() {
1953 testRecursiveDecomposition(CountedCompleterTest::forEach1);
1954 testRecursiveDecomposition(CountedCompleterTest::forEach2);
1955 testRecursiveDecomposition(CountedCompleterTest::forEach3);
1956 testRecursiveDecomposition(CountedCompleterTest::forEach4);
1957 }
1958
1959 }