ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinTask8Test.java
Revision: 1.27
Committed: Wed Aug 24 22:22:39 2016 UTC (7 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.26: +0 -1 lines
Log Message:
fix imports

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