4 |
|
* http://creativecommons.org/publicdomain/zero/1.0/ |
5 |
|
*/ |
6 |
|
|
7 |
< |
import static java.util.concurrent.TimeUnit.SECONDS; |
7 |
> |
import static java.util.concurrent.TimeUnit.MILLISECONDS; |
8 |
|
|
9 |
|
import java.util.Arrays; |
10 |
|
import java.util.HashSet; |
46 |
|
} |
47 |
|
|
48 |
|
private void testInvokeOnPool(ForkJoinPool pool, RecursiveAction a) { |
49 |
< |
try { |
49 |
> |
try (PoolCleaner cleaner = cleaner(pool)) { |
50 |
|
checkNotDone(a); |
51 |
|
|
52 |
|
assertNull(pool.invoke(a)); |
53 |
|
|
54 |
|
checkCompletedNormally(a); |
55 |
– |
} finally { |
56 |
– |
joinPool(pool); |
55 |
|
} |
56 |
|
} |
57 |
|
|
73 |
|
|
74 |
|
Thread.currentThread().interrupt(); |
75 |
|
try { |
76 |
< |
a.get(5L, SECONDS); |
76 |
> |
a.get(randomTimeout(), randomTimeUnit()); |
77 |
|
shouldThrow(); |
78 |
|
} catch (InterruptedException success) { |
79 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
80 |
|
} |
81 |
|
|
82 |
|
try { |
83 |
< |
a.get(0L, SECONDS); |
83 |
> |
a.get(randomExpiredTimeout(), randomTimeUnit()); |
84 |
|
shouldThrow(); |
85 |
|
} catch (TimeoutException success) { |
86 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
96 |
|
assertNull(a.join()); |
97 |
|
assertFalse(a.cancel(false)); |
98 |
|
assertFalse(a.cancel(true)); |
99 |
+ |
|
100 |
+ |
Object v1 = null, v2 = null; |
101 |
|
try { |
102 |
< |
assertNull(a.get()); |
103 |
< |
} catch (Throwable fail) { threadUnexpectedException(fail); } |
104 |
< |
try { |
105 |
< |
assertNull(a.get(5L, SECONDS)); |
102 |
> |
v1 = a.get(); |
103 |
> |
v2 = a.get(randomTimeout(), randomTimeUnit()); |
104 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
105 |
+ |
assertNull(v1); |
106 |
+ |
assertNull(v2); |
107 |
|
} |
108 |
|
|
109 |
|
void checkCancelled(RecursiveAction a) { |
127 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
128 |
|
|
129 |
|
try { |
130 |
< |
a.get(5L, SECONDS); |
130 |
> |
a.get(randomTimeout(), randomTimeUnit()); |
131 |
|
shouldThrow(); |
132 |
|
} catch (CancellationException success) { |
133 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
158 |
|
} catch (Throwable fail) { threadUnexpectedException(fail); } |
159 |
|
|
160 |
|
try { |
161 |
< |
a.get(5L, SECONDS); |
161 |
> |
a.get(randomTimeout(), randomTimeUnit()); |
162 |
|
shouldThrow(); |
163 |
|
} catch (ExecutionException success) { |
164 |
|
assertSame(t.getClass(), success.getCause().getClass()); |
170 |
|
public FJException(Throwable cause) { super(cause); } |
171 |
|
} |
172 |
|
|
173 |
< |
// A simple recursive action for testing |
173 |
> |
/** A simple recursive action for testing. */ |
174 |
|
final class FibAction extends CheckedRecursiveAction { |
175 |
|
final int number; |
176 |
|
int result; |
188 |
|
} |
189 |
|
} |
190 |
|
|
191 |
< |
// A recursive action failing in base case |
191 |
> |
/** A recursive action failing in base case. */ |
192 |
|
static final class FailingFibAction extends RecursiveAction { |
193 |
|
final int number; |
194 |
|
int result; |
260 |
|
RecursiveAction a = new CheckedRecursiveAction() { |
261 |
|
protected void realCompute() { |
262 |
|
FibAction f = new FibAction(8); |
263 |
< |
final Thread myself = Thread.currentThread(); |
263 |
> |
final Thread currentThread = Thread.currentThread(); |
264 |
|
|
265 |
|
// test join() |
266 |
|
assertSame(f, f.fork()); |
267 |
< |
myself.interrupt(); |
268 |
< |
assertTrue(myself.isInterrupted()); |
267 |
> |
currentThread.interrupt(); |
268 |
|
assertNull(f.join()); |
269 |
|
Thread.interrupted(); |
270 |
|
assertEquals(21, f.result); |
273 |
|
f = new FibAction(8); |
274 |
|
f.cancel(true); |
275 |
|
assertSame(f, f.fork()); |
276 |
< |
myself.interrupt(); |
278 |
< |
assertTrue(myself.isInterrupted()); |
276 |
> |
currentThread.interrupt(); |
277 |
|
try { |
278 |
|
f.join(); |
279 |
|
shouldThrow(); |
285 |
|
f = new FibAction(8); |
286 |
|
f.completeExceptionally(new FJException()); |
287 |
|
assertSame(f, f.fork()); |
288 |
< |
myself.interrupt(); |
291 |
< |
assertTrue(myself.isInterrupted()); |
288 |
> |
currentThread.interrupt(); |
289 |
|
try { |
290 |
|
f.join(); |
291 |
|
shouldThrow(); |
297 |
|
// test quietlyJoin() |
298 |
|
f = new FibAction(8); |
299 |
|
assertSame(f, f.fork()); |
300 |
< |
myself.interrupt(); |
304 |
< |
assertTrue(myself.isInterrupted()); |
300 |
> |
currentThread.interrupt(); |
301 |
|
f.quietlyJoin(); |
302 |
|
Thread.interrupted(); |
303 |
|
assertEquals(21, f.result); |
306 |
|
f = new FibAction(8); |
307 |
|
f.cancel(true); |
308 |
|
assertSame(f, f.fork()); |
309 |
< |
myself.interrupt(); |
314 |
< |
assertTrue(myself.isInterrupted()); |
309 |
> |
currentThread.interrupt(); |
310 |
|
f.quietlyJoin(); |
311 |
|
Thread.interrupted(); |
312 |
|
checkCancelled(f); |
314 |
|
f = new FibAction(8); |
315 |
|
f.completeExceptionally(new FJException()); |
316 |
|
assertSame(f, f.fork()); |
317 |
< |
myself.interrupt(); |
323 |
< |
assertTrue(myself.isInterrupted()); |
317 |
> |
currentThread.interrupt(); |
318 |
|
f.quietlyJoin(); |
319 |
|
Thread.interrupted(); |
320 |
|
checkCompletedAbnormally(f, f.getException()); |
329 |
|
* succeeds in the presence of interrupts |
330 |
|
*/ |
331 |
|
public void testJoinIgnoresInterruptsOutsideForkJoinPool() { |
332 |
< |
final SynchronousQueue<FibAction[]> sq = |
339 |
< |
new SynchronousQueue<FibAction[]>(); |
332 |
> |
final SynchronousQueue<FibAction[]> sq = new SynchronousQueue<>(); |
333 |
|
RecursiveAction a = new CheckedRecursiveAction() { |
334 |
|
protected void realCompute() throws InterruptedException { |
335 |
|
FibAction[] fibActions = new FibAction[6]; |
341 |
|
fibActions[4].cancel(true); |
342 |
|
fibActions[5].completeExceptionally(new FJException()); |
343 |
|
|
344 |
< |
for (int i = 0; i < fibActions.length; i++) |
345 |
< |
fibActions[i].fork(); |
344 |
> |
for (FibAction fibAction : fibActions) |
345 |
> |
fibAction.fork(); |
346 |
|
|
347 |
|
sq.put(fibActions); |
348 |
|
|
353 |
|
public void realRun() throws InterruptedException { |
354 |
|
FibAction[] fibActions = sq.take(); |
355 |
|
FibAction f; |
356 |
< |
final Thread myself = Thread.currentThread(); |
356 |
> |
final Thread currentThread = Thread.currentThread(); |
357 |
|
|
358 |
|
// test join() ------------ |
359 |
|
|
360 |
|
f = fibActions[0]; |
361 |
|
assertFalse(ForkJoinTask.inForkJoinPool()); |
362 |
< |
myself.interrupt(); |
370 |
< |
assertTrue(myself.isInterrupted()); |
362 |
> |
currentThread.interrupt(); |
363 |
|
assertNull(f.join()); |
364 |
|
assertTrue(Thread.interrupted()); |
365 |
|
assertEquals(21, f.result); |
366 |
|
checkCompletedNormally(f); |
367 |
|
|
368 |
|
f = fibActions[1]; |
369 |
< |
myself.interrupt(); |
378 |
< |
assertTrue(myself.isInterrupted()); |
369 |
> |
currentThread.interrupt(); |
370 |
|
try { |
371 |
|
f.join(); |
372 |
|
shouldThrow(); |
376 |
|
} |
377 |
|
|
378 |
|
f = fibActions[2]; |
379 |
< |
myself.interrupt(); |
389 |
< |
assertTrue(myself.isInterrupted()); |
379 |
> |
currentThread.interrupt(); |
380 |
|
try { |
381 |
|
f.join(); |
382 |
|
shouldThrow(); |
388 |
|
// test quietlyJoin() --------- |
389 |
|
|
390 |
|
f = fibActions[3]; |
391 |
< |
myself.interrupt(); |
402 |
< |
assertTrue(myself.isInterrupted()); |
391 |
> |
currentThread.interrupt(); |
392 |
|
f.quietlyJoin(); |
393 |
|
assertTrue(Thread.interrupted()); |
394 |
|
assertEquals(21, f.result); |
395 |
|
checkCompletedNormally(f); |
396 |
|
|
397 |
|
f = fibActions[4]; |
398 |
< |
myself.interrupt(); |
410 |
< |
assertTrue(myself.isInterrupted()); |
398 |
> |
currentThread.interrupt(); |
399 |
|
f.quietlyJoin(); |
400 |
|
assertTrue(Thread.interrupted()); |
401 |
|
checkCancelled(f); |
402 |
|
|
403 |
|
f = fibActions[5]; |
404 |
< |
myself.interrupt(); |
417 |
< |
assertTrue(myself.isInterrupted()); |
404 |
> |
currentThread.interrupt(); |
405 |
|
f.quietlyJoin(); |
406 |
|
assertTrue(Thread.interrupted()); |
407 |
|
assertTrue(f.getException() instanceof FJException); |
412 |
|
|
413 |
|
t = newStartedThread(r); |
414 |
|
testInvokeOnPool(mainPool(), a); |
415 |
< |
awaitTermination(t, LONG_DELAY_MS); |
415 |
> |
awaitTermination(t); |
416 |
|
|
417 |
|
a.reinitialize(); |
418 |
|
t = newStartedThread(r); |
419 |
|
testInvokeOnPool(singletonPool(), a); |
420 |
< |
awaitTermination(t, LONG_DELAY_MS); |
420 |
> |
awaitTermination(t); |
421 |
|
} |
422 |
|
|
423 |
|
/** |
443 |
|
protected void realCompute() throws Exception { |
444 |
|
FibAction f = new FibAction(8); |
445 |
|
assertSame(f, f.fork()); |
446 |
< |
assertNull(f.get(5L, SECONDS)); |
446 |
> |
assertNull(f.get(LONG_DELAY_MS, MILLISECONDS)); |
447 |
|
assertEquals(21, f.result); |
448 |
|
checkCompletedNormally(f); |
449 |
|
}}; |
459 |
|
FibAction f = new FibAction(8); |
460 |
|
assertSame(f, f.fork()); |
461 |
|
try { |
462 |
< |
f.get(5L, null); |
462 |
> |
f.get(randomTimeout(), null); |
463 |
|
shouldThrow(); |
464 |
|
} catch (NullPointerException success) {} |
465 |
|
}}; |
578 |
|
FailingFibAction f = new FailingFibAction(8); |
579 |
|
assertSame(f, f.fork()); |
580 |
|
try { |
581 |
< |
f.get(5L, SECONDS); |
581 |
> |
f.get(LONG_DELAY_MS, MILLISECONDS); |
582 |
|
shouldThrow(); |
583 |
|
} catch (ExecutionException success) { |
584 |
|
Throwable cause = success.getCause(); |
670 |
|
assertTrue(f.cancel(true)); |
671 |
|
assertSame(f, f.fork()); |
672 |
|
try { |
673 |
< |
f.get(5L, SECONDS); |
673 |
> |
f.get(LONG_DELAY_MS, MILLISECONDS); |
674 |
|
shouldThrow(); |
675 |
|
} catch (CancellationException success) { |
676 |
|
checkCancelled(f); |