ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.26
Committed: Wed Aug 10 01:28:14 2016 UTC (7 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.25: +3 -3 lines
Log Message:
introduce shuffle(T[]) utility method

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