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