ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.32
Committed: Sun Jul 22 20:42:51 2018 UTC (5 years, 9 months ago) by jsr166
Branch: MAIN
Changes since 1.31: +9 -5 lines
Log Message:
Fix errorprone warning [AssertionFailureIgnored]

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