ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.19
Committed: Mon Oct 5 22:59:29 2015 UTC (8 years, 6 months ago) by dl
Branch: MAIN
Changes since 1.18: +2 -2 lines
Log Message:
use volatile links in test class

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