ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.15
Committed: Tue Sep 8 23:56:19 2015 UTC (8 years, 7 months ago) by dl
Branch: MAIN
Changes since 1.14: +42 -0 lines
Log Message:
add testPollSubmission

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