ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/RecursiveActionTest.java
Revision: 1.51
Committed: Sat Oct 21 06:49:04 2017 UTC (6 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.50: +1 -1 lines
Log Message:
better exception handling

File Contents

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