ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.30
Committed: Sat Oct 21 06:54:19 2017 UTC (6 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.29: +1 -1 lines
Log Message:
better exception handling

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