ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.24
Committed: Sun Oct 11 15:34:06 2015 UTC (8 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.23: +1 -1 lines
Log Message:
whitespace

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