ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ForkJoinPool19Test.java
Revision: 1.3
Committed: Fri Nov 25 16:39:48 2022 UTC (17 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +2 -1 lines
Log Message:
whitespace

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6
7 import static java.util.concurrent.TimeUnit.MILLISECONDS;
8
9 import java.util.HashSet;
10 import java.util.concurrent.CancellationException;
11 import java.util.concurrent.CountedCompleter;
12 import java.util.concurrent.ExecutionException;
13 import java.util.concurrent.ForkJoinPool;
14 import java.util.concurrent.ForkJoinTask;
15 import java.util.concurrent.RecursiveAction;
16 import java.util.concurrent.TimeoutException;
17 import java.util.concurrent.Callable;
18
19 import junit.framework.Test;
20 import junit.framework.TestSuite;
21
22 /**
23 * Tests for ForkJoinPool and corresponding ForkJoinTask additions.
24 */
25 public class ForkJoinPool19Test extends JSR166TestCase {
26 public static void main(String[] args) {
27 main(suite(), args);
28 }
29
30 public static Test suite() {
31 return new TestSuite(ForkJoinPool8Test.class);
32 }
33
34 /**
35 * SetParallelism sets reported parallellism and returns previous value
36 */
37 public void testSetParallelism() {
38 final ForkJoinPool p = new ForkJoinPool(2);
39 assertEquals(2, p.getParallelism());
40 assertEquals(2, p.setParallelism(3));
41 assertEquals(3, p.setParallelism(2));
42 p.shutdown();
43 }
44
45 /**
46 * SetParallelism throws exception if argument out of bounds
47 */
48 public void testSetParallelismBadArgs() {
49 final ForkJoinPool p = new ForkJoinPool(2);
50 try {
51 p.setParallelism(0);
52 shouldThrow();
53 } catch (Exception success) {
54 }
55 try {
56 p.setParallelism(Integer.MAX_VALUE);
57 shouldThrow();
58 } catch (Exception success) {
59 }
60 assertEquals(2, p.getParallelism());
61 p.shutdown();
62 }
63
64
65 /*
66 * Some test methods adapted from RecursiveAction
67 */
68 private static ForkJoinPool mainPool() {
69 return new ForkJoinPool();
70 }
71
72 private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) {
73 try (PoolCleaner cleaner = cleaner(pool)) {
74 checkNotDone(a);
75 assertNull(pool.invoke(a));
76 checkCompletedNormally(a);
77 }
78 }
79
80 private void checkInvoke(ForkJoinTask<?> a) {
81 checkNotDone(a);
82 assertNull(a.invoke());
83 checkCompletedNormally(a);
84 }
85
86 void checkNotDone(ForkJoinTask<?> a) {
87 assertFalse(a.isDone());
88 assertFalse(a.isCompletedNormally());
89 assertFalse(a.isCompletedAbnormally());
90 assertFalse(a.isCancelled());
91 assertNull(a.getException());
92 assertNull(a.getRawResult());
93
94 if (! ForkJoinTask.inForkJoinPool()) {
95 Thread.currentThread().interrupt();
96 try {
97 a.get();
98 shouldThrow();
99 } catch (InterruptedException success) {
100 } catch (Throwable fail) { threadUnexpectedException(fail); }
101
102 Thread.currentThread().interrupt();
103 try {
104 a.get(randomTimeout(), randomTimeUnit());
105 shouldThrow();
106 } catch (InterruptedException success) {
107 } catch (Throwable fail) { threadUnexpectedException(fail); }
108 }
109
110 try {
111 a.get(randomExpiredTimeout(), randomTimeUnit());
112 shouldThrow();
113 } catch (TimeoutException success) {
114 } catch (Throwable fail) { threadUnexpectedException(fail); }
115 }
116
117 void checkCompletedNormally(ForkJoinTask<?> a) {
118 assertTrue(a.isDone());
119 assertFalse(a.isCancelled());
120 assertTrue(a.isCompletedNormally());
121 assertFalse(a.isCompletedAbnormally());
122 assertNull(a.getException());
123 assertNull(a.getRawResult());
124 assertNull(a.join());
125 assertFalse(a.cancel(false));
126 assertFalse(a.cancel(true));
127
128 Object v1 = null, v2 = null;
129 try {
130 v1 = a.get();
131 v2 = a.get(randomTimeout(), randomTimeUnit());
132 } catch (Throwable fail) { threadUnexpectedException(fail); }
133 assertNull(v1);
134 assertNull(v2);
135 }
136
137 void checkCancelled(ForkJoinTask<?> a) {
138 assertTrue(a.isDone());
139 assertTrue(a.isCancelled());
140 assertFalse(a.isCompletedNormally());
141 assertTrue(a.isCompletedAbnormally());
142 assertTrue(a.getException() instanceof CancellationException);
143 assertNull(a.getRawResult());
144
145 try {
146 a.join();
147 shouldThrow();
148 } catch (CancellationException success) {
149 } catch (Throwable fail) { threadUnexpectedException(fail); }
150
151 try {
152 a.get();
153 shouldThrow();
154 } catch (CancellationException success) {
155 } catch (Throwable fail) { threadUnexpectedException(fail); }
156
157 try {
158 a.get(randomTimeout(), randomTimeUnit());
159 shouldThrow();
160 } catch (CancellationException success) {
161 } catch (Throwable fail) { threadUnexpectedException(fail); }
162 }
163
164 void checkCompletedAbnormally(ForkJoinTask<?> a, Throwable t) {
165 assertTrue(a.isDone());
166 assertFalse(a.isCancelled());
167 assertFalse(a.isCompletedNormally());
168 assertTrue(a.isCompletedAbnormally());
169 assertSame(t.getClass(), a.getException().getClass());
170 assertNull(a.getRawResult());
171 assertFalse(a.cancel(false));
172 assertFalse(a.cancel(true));
173
174 try {
175 a.join();
176 shouldThrow();
177 } catch (Throwable expected) {
178 assertSame(expected.getClass(), t.getClass());
179 }
180
181 try {
182 a.get();
183 shouldThrow();
184 } catch (ExecutionException success) {
185 assertSame(t.getClass(), success.getCause().getClass());
186 } catch (Throwable fail) { threadUnexpectedException(fail); }
187
188 try {
189 a.get(randomTimeout(), randomTimeUnit());
190 shouldThrow();
191 } catch (ExecutionException success) {
192 assertSame(t.getClass(), success.getCause().getClass());
193 } catch (Throwable fail) { threadUnexpectedException(fail); }
194 }
195
196 public static final class FJException extends RuntimeException {
197 public FJException() { super(); }
198 public FJException(Throwable cause) { super(cause); }
199 }
200
201 /** A simple recursive action for testing. */
202 final class FibAction extends CheckedRecursiveAction {
203 final int number;
204 int result;
205 FibAction(int n) { number = n; }
206 protected void realCompute() {
207 int n = number;
208 if (n <= 1)
209 result = n;
210 else {
211 FibAction f1 = new FibAction(n - 1);
212 FibAction f2 = new FibAction(n - 2);
213 invokeAll(f1, f2);
214 result = f1.result + f2.result;
215 }
216 }
217 }
218
219 /** A recursive action failing in base case. */
220 static final class FailingFibAction extends RecursiveAction {
221 final int number;
222 int result;
223 FailingFibAction(int n) { number = n; }
224 public void compute() {
225 int n = number;
226 if (n <= 1)
227 throw new FJException();
228 else {
229 FailingFibAction f1 = new FailingFibAction(n - 1);
230 FailingFibAction f2 = new FailingFibAction(n - 2);
231 invokeAll(f1, f2);
232 result = f1.result + f2.result;
233 }
234 }
235 }
236
237 /**
238 * lazySubmit submits a task that is not executed until new
239 * workers are created or it is explicitly joined by a worker.
240 */
241 public void testLazySubmit() {
242 RecursiveAction a = new CheckedRecursiveAction() {
243 protected void realCompute() {
244 final ForkJoinPool p = mainPool();
245 FibAction f = new FibAction(8);
246 p.lazySubmit(f);
247 checkNotDone(f);
248 FibAction g = new FibAction(8);
249 p.submit(g);
250 g.join();
251 f.join();
252 assertEquals(21, f.result);
253 checkCompletedNormally(f);
254 }};
255 testInvokeOnPool(mainPool(), a);
256 }
257
258 /**
259 * quietlyInvoke task returns when task completes normally.
260 * isCompletedAbnormally and isCancelled return false for normally
261 * completed tasks
262 */
263 public void testQuietlyInvoke() {
264 RecursiveAction a = new CheckedRecursiveAction() {
265 protected void realCompute() {
266 FibAction f = new FibAction(8);
267 f.quietlyInvoke();
268 assertEquals(21, f.result);
269 checkCompletedNormally(f);
270 }};
271 checkInvoke(a);
272 }
273
274 /**
275 * join of a forked task returns when task completes
276 */
277 public void testForkJoin() {
278 RecursiveAction a = new CheckedRecursiveAction() {
279 protected void realCompute() {
280 FibAction f = new FibAction(8);
281 assertSame(f, f.fork());
282 assertNull(f.join());
283 assertEquals(21, f.result);
284 checkCompletedNormally(f);
285 }};
286 checkInvoke(a);
287 }
288
289 /**
290 * timed quietlyJoinUninterruptibly of a forked task succeeds in
291 * the presence of interrupts
292 */
293 public void testTimedQuietlyJoinUninterruptiblyInterrupts() {
294 RecursiveAction a = new CheckedRecursiveAction() {
295 protected void realCompute() {
296 FibAction f;
297 final Thread currentThread = Thread.currentThread();
298
299 // test quietlyJoin()
300 f = new FibAction(8);
301 assertSame(f, f.fork());
302 currentThread.interrupt();
303 f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS);
304 Thread.interrupted();
305 assertEquals(21, f.result);
306 checkCompletedNormally(f);
307
308 f = new FibAction(8);
309 f.cancel(true);
310 assertSame(f, f.fork());
311 currentThread.interrupt();
312 f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS);
313 Thread.interrupted();
314 checkCancelled(f);
315
316 f = new FibAction(8);
317 f.completeExceptionally(new FJException());
318 assertSame(f, f.fork());
319 currentThread.interrupt();
320 f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS);
321 Thread.interrupted();
322 checkCompletedAbnormally(f, f.getException());
323 }};
324 checkInvoke(a);
325 a.reinitialize();
326 checkInvoke(a);
327 }
328
329 /**
330 * timed quietlyJoin throws IE in the presence of interrupts
331 */
332 public void testTimedQuietlyJoinInterrupts() {
333 RecursiveAction a = new CheckedRecursiveAction() {
334 protected void realCompute() {
335 FibAction f;
336 final Thread currentThread = Thread.currentThread();
337
338 f = new FibAction(8);
339 assertSame(f, f.fork());
340 currentThread.interrupt();
341 try {
342 f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS);
343 } catch (InterruptedException success) {
344 }
345 Thread.interrupted();
346 f.quietlyJoin();
347
348 f = new FibAction(8);
349 f.cancel(true);
350 assertSame(f, f.fork());
351 currentThread.interrupt();
352 try {
353 f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS);
354 } catch (InterruptedException success) {
355 }
356 f.quietlyJoin();
357 checkCancelled(f);
358 }};
359 checkInvoke(a);
360 a.reinitialize();
361 checkInvoke(a);
362 }
363
364 /**
365 * timed quietlyJoin of a forked task returns when task completes
366 */
367 public void testForkTimedQuietlyJoin() {
368 RecursiveAction a = new CheckedRecursiveAction() {
369 protected void realCompute() throws Exception {
370 FibAction f = new FibAction(8);
371 assertSame(f, f.fork());
372 assertTrue(f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS));
373 assertEquals(21, f.result);
374 checkCompletedNormally(f);
375 }};
376 checkInvoke(a);
377 }
378
379 /**
380 * timed quietlyJoin with null time unit throws NPE
381 */
382 public void testForkTimedQuietlyJoinNPE() {
383 RecursiveAction a = new CheckedRecursiveAction() {
384 protected void realCompute() throws Exception {
385 FibAction f = new FibAction(8);
386 assertSame(f, f.fork());
387 try {
388 f.quietlyJoin(randomTimeout(), null);
389 shouldThrow();
390 } catch (NullPointerException success) {}
391 }};
392 checkInvoke(a);
393 }
394
395 /**
396 * quietlyInvoke task returns when task completes abnormally
397 */
398 public void testAbnormalTimedQuietlyJoin() {
399 RecursiveAction a = new CheckedRecursiveAction() {
400 protected void realCompute() throws Exception {
401 FailingFibAction f = new FailingFibAction(8);
402 assertSame(f, f.fork());
403 assertTrue(f.quietlyJoin(LONG_DELAY_MS, MILLISECONDS));
404 assertTrue(f.getException() instanceof FJException);
405 checkCompletedAbnormally(f, f.getException());
406 }};
407 checkInvoke(a);
408 }
409
410 /**
411 * timed quietlyJoinUninterruptibly of a forked task returns when task completes
412 */
413 public void testForkTimedQuietlyJoinUninterruptibly() {
414 RecursiveAction a = new CheckedRecursiveAction() {
415 protected void realCompute() throws Exception {
416 FibAction f = new FibAction(8);
417 assertSame(f, f.fork());
418 assertTrue(f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS));
419 assertEquals(21, f.result);
420 checkCompletedNormally(f);
421 }};
422 checkInvoke(a);
423 }
424
425 /**
426 * timed quietlyJoinUninterruptibly with null time unit throws NPE
427 */
428 public void testForkTimedQuietlyJoinUninterruptiblyNPE() {
429 RecursiveAction a = new CheckedRecursiveAction() {
430 protected void realCompute() throws Exception {
431 FibAction f = new FibAction(8);
432 assertSame(f, f.fork());
433 try {
434 f.quietlyJoinUninterruptibly(randomTimeout(), null);
435 shouldThrow();
436 } catch (NullPointerException success) {}
437 }};
438 checkInvoke(a);
439 }
440
441 /**
442 * quietlyInvoke task returns when task completes abnormally
443 */
444 public void testAbnormalTimedQuietlyJoinUninterruptibly() {
445 RecursiveAction a = new CheckedRecursiveAction() {
446 protected void realCompute() {
447 FailingFibAction f = new FailingFibAction(8);
448 assertSame(f, f.fork());
449 assertTrue(f.quietlyJoinUninterruptibly(LONG_DELAY_MS, MILLISECONDS));
450 assertTrue(f.getException() instanceof FJException);
451 checkCompletedAbnormally(f, f.getException());
452 }};
453 checkInvoke(a);
454 }
455
456 /**
457 * adaptInterruptible(callable).toString() contains toString of wrapped task
458 */
459 public void testAdaptInterruptible_Callable_toString() {
460 if (testImplementationDetails) {
461 Callable<String> c = () -> "";
462 ForkJoinTask<String> task = ForkJoinTask.adaptInterruptible(c);
463 assertEquals(
464 identityString(task) + "[Wrapped task = " + c.toString() + "]",
465 task.toString());
466 }
467 }
468
469 /**
470 * Implictly closing a new pool using try-with-resources terminates it
471 */
472 public void testClose() {
473 ForkJoinTask f = new FibAction(8);
474 ForkJoinPool pool = null;
475 try (ForkJoinPool p = new ForkJoinPool()) {
476 pool = p;
477 p.execute(f);
478 }
479 checkCompletedNormally(f);
480 assertTrue(pool != null && pool.isTerminated());
481 }
482
483 /**
484 * Implictly closing commonpool using try-with-resources does not
485 * terminate it
486 */
487 public void testCloseCommonPool() {
488 ForkJoinTask f = new FibAction(8);
489 ForkJoinPool pool;
490 try (ForkJoinPool p = ForkJoinPool.commonPool()) {
491 pool = p;
492 p.execute(f);
493 }
494 assertFalse(pool.isTerminated());
495 }
496 }