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