ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/RecursiveTaskTest.java
Revision: 1.43
Committed: Wed Jan 27 01:57:24 2021 UTC (3 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.42: +46 -46 lines
Log Message:
use diamond <> pervasively

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 import static java.util.concurrent.TimeUnit.MILLISECONDS;
8
9 import java.util.HashSet;
10 import java.util.concurrent.CancellationException;
11 import java.util.concurrent.ExecutionException;
12 import java.util.concurrent.ForkJoinPool;
13 import java.util.concurrent.ForkJoinTask;
14 import java.util.concurrent.RecursiveTask;
15 import java.util.concurrent.TimeoutException;
16
17 import junit.framework.Test;
18 import junit.framework.TestSuite;
19
20 public class RecursiveTaskTest extends JSR166TestCase {
21
22 public static void main(String[] args) {
23 main(suite(), args);
24 }
25 public static Test suite() {
26 return new TestSuite(RecursiveTaskTest.class);
27 }
28
29 private static ForkJoinPool mainPool() {
30 return new ForkJoinPool();
31 }
32
33 private static ForkJoinPool singletonPool() {
34 return new ForkJoinPool(1);
35 }
36
37 private static ForkJoinPool asyncSingletonPool() {
38 return new ForkJoinPool(1,
39 ForkJoinPool.defaultForkJoinWorkerThreadFactory,
40 null, true);
41 }
42
43 private <T> T testInvokeOnPool(ForkJoinPool pool, RecursiveTask<T> a) {
44 try (PoolCleaner cleaner = cleaner(pool)) {
45 checkNotDone(a);
46
47 T result = pool.invoke(a);
48
49 checkCompletedNormally(a, result);
50 return result;
51 }
52 }
53
54 void checkNotDone(RecursiveTask<?> a) {
55 assertFalse(a.isDone());
56 assertFalse(a.isCompletedNormally());
57 assertFalse(a.isCompletedAbnormally());
58 assertFalse(a.isCancelled());
59 assertNull(a.getException());
60 assertNull(a.getRawResult());
61
62 if (! ForkJoinTask.inForkJoinPool()) {
63 Thread.currentThread().interrupt();
64 try {
65 a.get();
66 shouldThrow();
67 } catch (InterruptedException success) {
68 } catch (Throwable fail) { threadUnexpectedException(fail); }
69
70 Thread.currentThread().interrupt();
71 try {
72 a.get(randomTimeout(), randomTimeUnit());
73 shouldThrow();
74 } catch (InterruptedException success) {
75 } catch (Throwable fail) { threadUnexpectedException(fail); }
76 }
77
78 try {
79 a.get(randomExpiredTimeout(), randomTimeUnit());
80 shouldThrow();
81 } catch (TimeoutException success) {
82 } catch (Throwable fail) { threadUnexpectedException(fail); }
83 }
84
85 <T> void checkCompletedNormally(RecursiveTask<T> a, T expectedValue) {
86 assertTrue(a.isDone());
87 assertFalse(a.isCancelled());
88 assertTrue(a.isCompletedNormally());
89 assertFalse(a.isCompletedAbnormally());
90 assertNull(a.getException());
91 assertSame(expectedValue, a.getRawResult());
92 assertSame(expectedValue, a.join());
93 assertFalse(a.cancel(false));
94 assertFalse(a.cancel(true));
95
96 T v1 = null, v2 = null;
97 try {
98 v1 = a.get();
99 v2 = a.get(randomTimeout(), randomTimeUnit());
100 } catch (Throwable fail) { threadUnexpectedException(fail); }
101 assertSame(expectedValue, v1);
102 assertSame(expectedValue, v2);
103 }
104
105 /**
106 * Waits for the task to complete, and checks that when it does,
107 * it will have an Integer result equals to the given int.
108 */
109 void checkCompletesNormally(RecursiveTask<Integer> a, int expectedValue) {
110 Integer r = a.join();
111 assertEquals(expectedValue, (int) r);
112 checkCompletedNormally(a, r);
113 }
114
115 /**
116 * Like checkCompletesNormally, but verifies that the task has
117 * already completed.
118 */
119 void checkCompletedNormally(RecursiveTask<Integer> a, int expectedValue) {
120 Integer r = a.getRawResult();
121 assertEquals(expectedValue, (int) r);
122 checkCompletedNormally(a, r);
123 }
124
125 void checkCancelled(RecursiveTask<?> a) {
126 assertTrue(a.isDone());
127 assertTrue(a.isCancelled());
128 assertFalse(a.isCompletedNormally());
129 assertTrue(a.isCompletedAbnormally());
130 assertTrue(a.getException() instanceof CancellationException);
131 assertNull(a.getRawResult());
132
133 try {
134 a.join();
135 shouldThrow();
136 } catch (CancellationException success) {
137 } catch (Throwable fail) { threadUnexpectedException(fail); }
138
139 try {
140 a.get();
141 shouldThrow();
142 } catch (CancellationException success) {
143 } catch (Throwable fail) { threadUnexpectedException(fail); }
144
145 try {
146 a.get(randomTimeout(), randomTimeUnit());
147 shouldThrow();
148 } catch (CancellationException success) {
149 } catch (Throwable fail) { threadUnexpectedException(fail); }
150 }
151
152 void checkCompletedAbnormally(RecursiveTask<?> 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
162 try {
163 a.join();
164 shouldThrow();
165 } catch (Throwable expected) {
166 assertSame(t.getClass(), expected.getClass());
167 }
168
169 try {
170 a.get();
171 shouldThrow();
172 } catch (ExecutionException success) {
173 assertSame(t.getClass(), success.getCause().getClass());
174 } catch (Throwable fail) { threadUnexpectedException(fail); }
175
176 try {
177 a.get(randomTimeout(), randomTimeUnit());
178 shouldThrow();
179 } catch (ExecutionException success) {
180 assertSame(t.getClass(), success.getCause().getClass());
181 } catch (Throwable fail) { threadUnexpectedException(fail); }
182 }
183
184 public static final class FJException extends RuntimeException {
185 public FJException() { super(); }
186 }
187
188 /** An invalid return value for Fib. */
189 static final Integer NoResult = Integer.valueOf(-17);
190
191 /** A simple recursive task for testing. */
192 final class FibTask extends CheckedRecursiveTask<Integer> {
193 final int number;
194 FibTask(int n) { number = n; }
195 public Integer realCompute() {
196 int n = number;
197 if (n <= 1)
198 return n;
199 FibTask f1 = new FibTask(n - 1);
200 f1.fork();
201 return new FibTask(n - 2).compute() + f1.join();
202 }
203
204 public void publicSetRawResult(Integer result) {
205 setRawResult(result);
206 }
207 }
208
209 /** A recursive action failing in base case. */
210 final class FailingFibTask extends RecursiveTask<Integer> {
211 final int number;
212 int result;
213 FailingFibTask(int n) { number = n; }
214 public Integer compute() {
215 int n = number;
216 if (n <= 1)
217 throw new FJException();
218 FailingFibTask f1 = new FailingFibTask(n - 1);
219 f1.fork();
220 return new FibTask(n - 2).compute() + f1.join();
221 }
222 }
223
224 /**
225 * invoke returns value when task completes normally.
226 * isCompletedAbnormally and isCancelled return false for normally
227 * completed tasks. getRawResult of a completed non-null task
228 * returns value;
229 */
230 public void testInvoke() {
231 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
232 public Integer realCompute() {
233 FibTask f = new FibTask(8);
234 Integer r = f.invoke();
235 assertEquals(21, (int) r);
236 checkCompletedNormally(f, r);
237 return r;
238 }};
239 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
240 }
241
242 /**
243 * quietlyInvoke task returns when task completes normally.
244 * isCompletedAbnormally and isCancelled return false for normally
245 * completed tasks
246 */
247 public void testQuietlyInvoke() {
248 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
249 public Integer realCompute() {
250 FibTask f = new FibTask(8);
251 f.quietlyInvoke();
252 checkCompletedNormally(f, 21);
253 return NoResult;
254 }};
255 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
256 }
257
258 /**
259 * join of a forked task returns when task completes
260 */
261 public void testForkJoin() {
262 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
263 public Integer realCompute() {
264 FibTask f = new FibTask(8);
265 assertSame(f, f.fork());
266 Integer r = f.join();
267 assertEquals(21, (int) r);
268 checkCompletedNormally(f, r);
269 return r;
270 }};
271 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
272 }
273
274 /**
275 * get of a forked task returns when task completes
276 */
277 public void testForkGet() {
278 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
279 public Integer realCompute() throws Exception {
280 FibTask f = new FibTask(8);
281 assertSame(f, f.fork());
282 Integer r = f.get();
283 assertEquals(21, (int) r);
284 checkCompletedNormally(f, r);
285 return r;
286 }};
287 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
288 }
289
290 /**
291 * timed get of a forked task returns when task completes
292 */
293 public void testForkTimedGet() {
294 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
295 public Integer realCompute() throws Exception {
296 FibTask f = new FibTask(8);
297 assertSame(f, f.fork());
298 Integer r = f.get(LONG_DELAY_MS, MILLISECONDS);
299 assertEquals(21, (int) r);
300 checkCompletedNormally(f, r);
301 return r;
302 }};
303 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
304 }
305
306 /**
307 * quietlyJoin of a forked task returns when task completes
308 */
309 public void testForkQuietlyJoin() {
310 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
311 public Integer realCompute() {
312 FibTask f = new FibTask(8);
313 assertSame(f, f.fork());
314 f.quietlyJoin();
315 Integer r = f.getRawResult();
316 assertEquals(21, (int) r);
317 checkCompletedNormally(f, r);
318 return r;
319 }};
320 assertEquals(21, (int) testInvokeOnPool(mainPool(), a));
321 }
322
323 /**
324 * helpQuiesce returns when tasks are complete.
325 * getQueuedTaskCount returns 0 when quiescent
326 */
327 public void testForkHelpQuiesce() {
328 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
329 public Integer realCompute() {
330 FibTask f = new FibTask(8);
331 assertSame(f, f.fork());
332 helpQuiesce();
333 while (!f.isDone()) // wait out race
334 ;
335 assertEquals(0, getQueuedTaskCount());
336 checkCompletedNormally(f, 21);
337 return NoResult;
338 }};
339 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
340 }
341
342 /**
343 * invoke task throws exception when task completes abnormally
344 */
345 public void testAbnormalInvoke() {
346 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
347 public Integer realCompute() {
348 FailingFibTask f = new FailingFibTask(8);
349 try {
350 f.invoke();
351 shouldThrow();
352 } catch (FJException success) {
353 checkCompletedAbnormally(f, success);
354 }
355 return NoResult;
356 }};
357 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
358 }
359
360 /**
361 * quietlyInvoke task returns when task completes abnormally
362 */
363 public void testAbnormalQuietlyInvoke() {
364 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
365 public Integer realCompute() {
366 FailingFibTask f = new FailingFibTask(8);
367 f.quietlyInvoke();
368 assertTrue(f.getException() instanceof FJException);
369 checkCompletedAbnormally(f, f.getException());
370 return NoResult;
371 }};
372 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
373 }
374
375 /**
376 * join of a forked task throws exception when task completes abnormally
377 */
378 public void testAbnormalForkJoin() {
379 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
380 public Integer realCompute() {
381 FailingFibTask f = new FailingFibTask(8);
382 assertSame(f, f.fork());
383 try {
384 f.join();
385 shouldThrow();
386 } catch (FJException success) {
387 checkCompletedAbnormally(f, success);
388 }
389 return NoResult;
390 }};
391 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
392 }
393
394 /**
395 * get of a forked task throws exception when task completes abnormally
396 */
397 public void testAbnormalForkGet() {
398 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
399 public Integer realCompute() throws Exception {
400 FailingFibTask f = new FailingFibTask(8);
401 assertSame(f, f.fork());
402 try {
403 f.get();
404 shouldThrow();
405 } catch (ExecutionException success) {
406 Throwable cause = success.getCause();
407 assertTrue(cause instanceof FJException);
408 checkCompletedAbnormally(f, cause);
409 }
410 return NoResult;
411 }};
412 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
413 }
414
415 /**
416 * timed get of a forked task throws exception when task completes abnormally
417 */
418 public void testAbnormalForkTimedGet() {
419 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
420 public Integer realCompute() throws Exception {
421 FailingFibTask f = new FailingFibTask(8);
422 assertSame(f, f.fork());
423 try {
424 f.get(LONG_DELAY_MS, MILLISECONDS);
425 shouldThrow();
426 } catch (ExecutionException success) {
427 Throwable cause = success.getCause();
428 assertTrue(cause instanceof FJException);
429 checkCompletedAbnormally(f, cause);
430 }
431 return NoResult;
432 }};
433 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
434 }
435
436 /**
437 * quietlyJoin of a forked task returns when task completes abnormally
438 */
439 public void testAbnormalForkQuietlyJoin() {
440 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
441 public Integer realCompute() {
442 FailingFibTask f = new FailingFibTask(8);
443 assertSame(f, f.fork());
444 f.quietlyJoin();
445 assertTrue(f.getException() instanceof FJException);
446 checkCompletedAbnormally(f, f.getException());
447 return NoResult;
448 }};
449 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
450 }
451
452 /**
453 * invoke task throws exception when task cancelled
454 */
455 public void testCancelledInvoke() {
456 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
457 public Integer realCompute() {
458 FibTask f = new FibTask(8);
459 assertTrue(f.cancel(true));
460 try {
461 f.invoke();
462 shouldThrow();
463 } catch (CancellationException success) {
464 checkCancelled(f);
465 }
466 return NoResult;
467 }};
468 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
469 }
470
471 /**
472 * join of a forked task throws exception when task cancelled
473 */
474 public void testCancelledForkJoin() {
475 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
476 public Integer realCompute() {
477 FibTask f = new FibTask(8);
478 assertTrue(f.cancel(true));
479 assertSame(f, f.fork());
480 try {
481 f.join();
482 shouldThrow();
483 } catch (CancellationException success) {
484 checkCancelled(f);
485 }
486 return NoResult;
487 }};
488 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
489 }
490
491 /**
492 * get of a forked task throws exception when task cancelled
493 */
494 public void testCancelledForkGet() {
495 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
496 public Integer realCompute() throws Exception {
497 FibTask f = new FibTask(8);
498 assertTrue(f.cancel(true));
499 assertSame(f, f.fork());
500 try {
501 f.get();
502 shouldThrow();
503 } catch (CancellationException success) {
504 checkCancelled(f);
505 }
506 return NoResult;
507 }};
508 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
509 }
510
511 /**
512 * timed get of a forked task throws exception when task cancelled
513 */
514 public void testCancelledForkTimedGet() {
515 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
516 public Integer realCompute() throws Exception {
517 FibTask f = new FibTask(8);
518 assertTrue(f.cancel(true));
519 assertSame(f, f.fork());
520 try {
521 f.get(LONG_DELAY_MS, MILLISECONDS);
522 shouldThrow();
523 } catch (CancellationException success) {
524 checkCancelled(f);
525 }
526 return NoResult;
527 }};
528 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
529 }
530
531 /**
532 * quietlyJoin of a forked task returns when task cancelled
533 */
534 public void testCancelledForkQuietlyJoin() {
535 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
536 public Integer realCompute() {
537 FibTask f = new FibTask(8);
538 assertTrue(f.cancel(true));
539 assertSame(f, f.fork());
540 f.quietlyJoin();
541 checkCancelled(f);
542 return NoResult;
543 }};
544 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
545 }
546
547 /**
548 * getPool of executing task returns its pool
549 */
550 public void testGetPool() {
551 final ForkJoinPool mainPool = mainPool();
552 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
553 public Integer realCompute() {
554 assertSame(mainPool, getPool());
555 return NoResult;
556 }};
557 assertSame(NoResult, testInvokeOnPool(mainPool, a));
558 }
559
560 /**
561 * getPool of non-FJ task returns null
562 */
563 public void testGetPool2() {
564 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
565 public Integer realCompute() {
566 assertNull(getPool());
567 return NoResult;
568 }};
569 assertSame(NoResult, a.invoke());
570 }
571
572 /**
573 * inForkJoinPool of executing task returns true
574 */
575 public void testInForkJoinPool() {
576 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
577 public Integer realCompute() {
578 assertTrue(inForkJoinPool());
579 return NoResult;
580 }};
581 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
582 }
583
584 /**
585 * inForkJoinPool of non-FJ task returns false
586 */
587 public void testInForkJoinPool2() {
588 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
589 public Integer realCompute() {
590 assertFalse(inForkJoinPool());
591 return NoResult;
592 }};
593 assertSame(NoResult, a.invoke());
594 }
595
596 /**
597 * The value set by setRawResult is returned by getRawResult
598 */
599 public void testSetRawResult() {
600 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
601 public Integer realCompute() {
602 setRawResult(NoResult);
603 assertSame(NoResult, getRawResult());
604 return NoResult;
605 }
606 };
607 assertSame(NoResult, a.invoke());
608 }
609
610 /**
611 * A reinitialized normally completed task may be re-invoked
612 */
613 public void testReinitialize() {
614 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
615 public Integer realCompute() {
616 FibTask f = new FibTask(8);
617 checkNotDone(f);
618
619 for (int i = 0; i < 3; i++) {
620 Integer r = f.invoke();
621 assertEquals(21, (int) r);
622 checkCompletedNormally(f, r);
623 f.reinitialize();
624 f.publicSetRawResult(null);
625 checkNotDone(f);
626 }
627 return NoResult;
628 }};
629 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
630 }
631
632 /**
633 * A reinitialized abnormally completed task may be re-invoked
634 */
635 public void testReinitializeAbnormal() {
636 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
637 public Integer realCompute() {
638 FailingFibTask f = new FailingFibTask(8);
639 checkNotDone(f);
640
641 for (int i = 0; i < 3; i++) {
642 try {
643 f.invoke();
644 shouldThrow();
645 } catch (FJException success) {
646 checkCompletedAbnormally(f, success);
647 }
648 f.reinitialize();
649 checkNotDone(f);
650 }
651 return NoResult;
652 }};
653 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
654 }
655
656 /**
657 * invoke task throws exception after invoking completeExceptionally
658 */
659 public void testCompleteExceptionally() {
660 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
661 public Integer realCompute() {
662 FibTask f = new FibTask(8);
663 f.completeExceptionally(new FJException());
664 try {
665 f.invoke();
666 shouldThrow();
667 } catch (FJException success) {
668 checkCompletedAbnormally(f, success);
669 }
670 return NoResult;
671 }};
672 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
673 }
674
675 /**
676 * invoke task suppresses execution invoking complete
677 */
678 public void testComplete() {
679 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
680 public Integer realCompute() {
681 FibTask f = new FibTask(8);
682 f.complete(NoResult);
683 Integer r = f.invoke();
684 assertSame(NoResult, r);
685 checkCompletedNormally(f, NoResult);
686 return r;
687 }};
688 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
689 }
690
691 /**
692 * invokeAll(t1, t2) invokes all task arguments
693 */
694 public void testInvokeAll2() {
695 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
696 public Integer realCompute() {
697 FibTask f = new FibTask(8);
698 FibTask g = new FibTask(9);
699 invokeAll(f, g);
700 checkCompletedNormally(f, 21);
701 checkCompletedNormally(g, 34);
702 return NoResult;
703 }};
704 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
705 }
706
707 /**
708 * invokeAll(tasks) with 1 argument invokes task
709 */
710 public void testInvokeAll1() {
711 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
712 public Integer realCompute() {
713 FibTask f = new FibTask(8);
714 invokeAll(f);
715 checkCompletedNormally(f, 21);
716 return NoResult;
717 }};
718 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
719 }
720
721 /**
722 * invokeAll(tasks) with > 2 argument invokes tasks
723 */
724 public void testInvokeAll3() {
725 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
726 public Integer realCompute() {
727 FibTask f = new FibTask(8);
728 FibTask g = new FibTask(9);
729 FibTask h = new FibTask(7);
730 invokeAll(f, g, h);
731 assertTrue(f.isDone());
732 assertTrue(g.isDone());
733 assertTrue(h.isDone());
734 checkCompletedNormally(f, 21);
735 checkCompletedNormally(g, 34);
736 checkCompletedNormally(h, 13);
737 return NoResult;
738 }};
739 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
740 }
741
742 /**
743 * invokeAll(collection) invokes all tasks in the collection
744 */
745 public void testInvokeAllCollection() {
746 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
747 public Integer realCompute() {
748 FibTask f = new FibTask(8);
749 FibTask g = new FibTask(9);
750 FibTask h = new FibTask(7);
751 HashSet<ForkJoinTask<?>> set = new HashSet<>();
752 set.add(f);
753 set.add(g);
754 set.add(h);
755 invokeAll(set);
756 assertTrue(f.isDone());
757 assertTrue(g.isDone());
758 assertTrue(h.isDone());
759 checkCompletedNormally(f, 21);
760 checkCompletedNormally(g, 34);
761 checkCompletedNormally(h, 13);
762 return NoResult;
763 }};
764 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
765 }
766
767 /**
768 * invokeAll(tasks) with any null task throws NPE
769 */
770 public void testInvokeAllNPE() {
771 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
772 public Integer realCompute() {
773 FibTask f = new FibTask(8);
774 FibTask g = new FibTask(9);
775 FibTask h = null;
776 try {
777 invokeAll(f, g, h);
778 shouldThrow();
779 } catch (NullPointerException success) {}
780 return NoResult;
781 }};
782 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
783 }
784
785 /**
786 * invokeAll(t1, t2) throw exception if any task does
787 */
788 public void testAbnormalInvokeAll2() {
789 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
790 public Integer realCompute() {
791 FibTask f = new FibTask(8);
792 FailingFibTask g = new FailingFibTask(9);
793 try {
794 invokeAll(f, g);
795 shouldThrow();
796 } catch (FJException success) {
797 checkCompletedAbnormally(g, success);
798 }
799 return NoResult;
800 }};
801 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
802 }
803
804 /**
805 * invokeAll(tasks) with 1 argument throws exception if task does
806 */
807 public void testAbnormalInvokeAll1() {
808 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
809 public Integer realCompute() {
810 FailingFibTask g = new FailingFibTask(9);
811 try {
812 invokeAll(g);
813 shouldThrow();
814 } catch (FJException success) {
815 checkCompletedAbnormally(g, success);
816 }
817 return NoResult;
818 }};
819 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
820 }
821
822 /**
823 * invokeAll(tasks) with > 2 argument throws exception if any task does
824 */
825 public void testAbnormalInvokeAll3() {
826 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
827 public Integer realCompute() {
828 FibTask f = new FibTask(8);
829 FailingFibTask g = new FailingFibTask(9);
830 FibTask h = new FibTask(7);
831 try {
832 invokeAll(f, g, h);
833 shouldThrow();
834 } catch (FJException success) {
835 checkCompletedAbnormally(g, success);
836 }
837 return NoResult;
838 }};
839 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
840 }
841
842 /**
843 * invokeAll(collection) throws exception if any task does
844 */
845 public void testAbnormalInvokeAllCollection() {
846 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
847 public Integer realCompute() {
848 FailingFibTask f = new FailingFibTask(8);
849 FibTask g = new FibTask(9);
850 FibTask h = new FibTask(7);
851 HashSet<ForkJoinTask<?>> set = new HashSet<>();
852 set.add(f);
853 set.add(g);
854 set.add(h);
855 try {
856 invokeAll(set);
857 shouldThrow();
858 } catch (FJException success) {
859 checkCompletedAbnormally(f, success);
860 }
861 return NoResult;
862 }};
863 assertSame(NoResult, testInvokeOnPool(mainPool(), a));
864 }
865
866 /**
867 * tryUnfork returns true for most recent unexecuted task,
868 * and suppresses execution
869 */
870 public void testTryUnfork() {
871 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
872 public Integer realCompute() {
873 FibTask g = new FibTask(9);
874 assertSame(g, g.fork());
875 FibTask f = new FibTask(8);
876 assertSame(f, f.fork());
877 assertTrue(f.tryUnfork());
878 helpQuiesce();
879 checkNotDone(f);
880 checkCompletedNormally(g, 34);
881 return NoResult;
882 }};
883 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
884 }
885
886 /**
887 * getSurplusQueuedTaskCount returns > 0 when
888 * there are more tasks than threads
889 */
890 public void testGetSurplusQueuedTaskCount() {
891 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
892 public Integer realCompute() {
893 FibTask h = new FibTask(7);
894 assertSame(h, h.fork());
895 FibTask g = new FibTask(9);
896 assertSame(g, g.fork());
897 FibTask f = new FibTask(8);
898 assertSame(f, f.fork());
899 assertTrue(getSurplusQueuedTaskCount() > 0);
900 helpQuiesce();
901 assertEquals(0, getSurplusQueuedTaskCount());
902 checkCompletedNormally(f, 21);
903 checkCompletedNormally(g, 34);
904 checkCompletedNormally(h, 13);
905 return NoResult;
906 }};
907 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
908 }
909
910 /**
911 * peekNextLocalTask returns most recent unexecuted task.
912 */
913 public void testPeekNextLocalTask() {
914 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
915 public Integer realCompute() {
916 FibTask g = new FibTask(9);
917 assertSame(g, g.fork());
918 FibTask f = new FibTask(8);
919 assertSame(f, f.fork());
920 assertSame(f, peekNextLocalTask());
921 checkCompletesNormally(f, 21);
922 helpQuiesce();
923 checkCompletedNormally(g, 34);
924 return NoResult;
925 }};
926 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
927 }
928
929 /**
930 * pollNextLocalTask returns most recent unexecuted task
931 * without executing it
932 */
933 public void testPollNextLocalTask() {
934 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
935 public Integer realCompute() {
936 FibTask g = new FibTask(9);
937 assertSame(g, g.fork());
938 FibTask f = new FibTask(8);
939 assertSame(f, f.fork());
940 assertSame(f, pollNextLocalTask());
941 helpQuiesce();
942 checkNotDone(f);
943 checkCompletedNormally(g, 34);
944 return NoResult;
945 }};
946 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
947 }
948
949 /**
950 * pollTask returns an unexecuted task without executing it
951 */
952 public void testPollTask() {
953 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
954 public Integer realCompute() {
955 FibTask g = new FibTask(9);
956 assertSame(g, g.fork());
957 FibTask f = new FibTask(8);
958 assertSame(f, f.fork());
959 assertSame(f, pollTask());
960 helpQuiesce();
961 checkNotDone(f);
962 checkCompletedNormally(g, 34);
963 return NoResult;
964 }};
965 assertSame(NoResult, testInvokeOnPool(singletonPool(), a));
966 }
967
968 /**
969 * peekNextLocalTask returns least recent unexecuted task in async mode
970 */
971 public void testPeekNextLocalTaskAsync() {
972 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
973 public Integer realCompute() {
974 FibTask g = new FibTask(9);
975 assertSame(g, g.fork());
976 FibTask f = new FibTask(8);
977 assertSame(f, f.fork());
978 assertSame(g, peekNextLocalTask());
979 assertEquals(21, (int) f.join());
980 helpQuiesce();
981 checkCompletedNormally(f, 21);
982 checkCompletedNormally(g, 34);
983 return NoResult;
984 }};
985 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
986 }
987
988 /**
989 * pollNextLocalTask returns least recent unexecuted task without
990 * executing it, in async mode
991 */
992 public void testPollNextLocalTaskAsync() {
993 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
994 public Integer realCompute() {
995 FibTask g = new FibTask(9);
996 assertSame(g, g.fork());
997 FibTask f = new FibTask(8);
998 assertSame(f, f.fork());
999 assertSame(g, pollNextLocalTask());
1000 helpQuiesce();
1001 checkCompletedNormally(f, 21);
1002 checkNotDone(g);
1003 return NoResult;
1004 }};
1005 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
1006 }
1007
1008 /**
1009 * pollTask returns an unexecuted task without executing it, in
1010 * async mode
1011 */
1012 public void testPollTaskAsync() {
1013 RecursiveTask<Integer> a = new CheckedRecursiveTask<>() {
1014 public Integer realCompute() {
1015 FibTask g = new FibTask(9);
1016 assertSame(g, g.fork());
1017 FibTask f = new FibTask(8);
1018 assertSame(f, f.fork());
1019 assertSame(g, pollTask());
1020 helpQuiesce();
1021 checkCompletedNormally(f, 21);
1022 checkNotDone(g);
1023 return NoResult;
1024 }};
1025 assertSame(NoResult, testInvokeOnPool(asyncSingletonPool(), a));
1026 }
1027
1028 }