ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.44
Committed: Sun May 24 01:42:14 2015 UTC (8 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.43: +3 -3 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 dl 1.1 /*
2 dl 1.10 * 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.24 * http://creativecommons.org/publicdomain/zero/1.0/
5 jsr166 1.12 * Other contributors include Andrew Wright, Jeffrey Hayes,
6     * Pat Fisher, Mike Judd.
7 dl 1.1 */
8    
9 jsr166 1.40 import static java.util.concurrent.TimeUnit.MILLISECONDS;
10     import static java.util.concurrent.TimeUnit.NANOSECONDS;
11     import static java.util.concurrent.TimeUnit.SECONDS;
12    
13     import java.util.ArrayList;
14     import java.util.List;
15     import java.util.NoSuchElementException;
16 jsr166 1.26 import java.util.concurrent.Callable;
17     import java.util.concurrent.CancellationException;
18     import java.util.concurrent.CountDownLatch;
19 jsr166 1.40 import java.util.concurrent.ExecutionException;
20     import java.util.concurrent.Executors;
21 jsr166 1.39 import java.util.concurrent.ExecutorService;
22 jsr166 1.26 import java.util.concurrent.Future;
23     import java.util.concurrent.FutureTask;
24     import java.util.concurrent.TimeoutException;
25 jsr166 1.29 import java.util.concurrent.atomic.AtomicInteger;
26 jsr166 1.40
27     import junit.framework.Test;
28     import junit.framework.TestSuite;
29 dl 1.1
30 dl 1.4 public class FutureTaskTest extends JSR166TestCase {
31 dl 1.1
32     public static void main(String[] args) {
33 jsr166 1.43 main(suite(), args);
34 dl 1.1 }
35     public static Test suite() {
36 jsr166 1.16 return new TestSuite(FutureTaskTest.class);
37 dl 1.1 }
38    
39 jsr166 1.29 void checkIsDone(Future<?> f) {
40     assertTrue(f.isDone());
41     assertFalse(f.cancel(false));
42     assertFalse(f.cancel(true));
43     if (f instanceof PublicFutureTask) {
44     PublicFutureTask pf = (PublicFutureTask) f;
45     assertEquals(1, pf.doneCount());
46     assertFalse(pf.runAndReset());
47     assertEquals(1, pf.doneCount());
48 jsr166 1.37 Object r = null; Object exInfo = null;
49     try {
50     r = f.get();
51     } catch (CancellationException t) {
52     exInfo = CancellationException.class;
53     } catch (ExecutionException t) {
54     exInfo = t.getCause();
55     } catch (Throwable t) {
56     threadUnexpectedException(t);
57     }
58 jsr166 1.29
59     // Check that run and runAndReset have no effect.
60     int savedRunCount = pf.runCount();
61     pf.run();
62     pf.runAndReset();
63     assertEquals(savedRunCount, pf.runCount());
64 jsr166 1.37 try {
65     assertSame(r, f.get());
66     } catch (CancellationException t) {
67     assertSame(exInfo, CancellationException.class);
68     } catch (ExecutionException t) {
69     assertSame(exInfo, t.getCause());
70     } catch (Throwable t) {
71     threadUnexpectedException(t);
72     }
73 jsr166 1.29 assertTrue(f.isDone());
74     }
75     }
76    
77 jsr166 1.22 void checkNotDone(Future<?> f) {
78     assertFalse(f.isDone());
79     assertFalse(f.isCancelled());
80 jsr166 1.29 if (f instanceof PublicFutureTask) {
81     PublicFutureTask pf = (PublicFutureTask) f;
82     assertEquals(0, pf.doneCount());
83     assertEquals(0, pf.setCount());
84     assertEquals(0, pf.setExceptionCount());
85     }
86     }
87    
88     void checkIsRunning(Future<?> f) {
89     checkNotDone(f);
90     if (f instanceof FutureTask) {
91     FutureTask ft = (FutureTask<?>) f;
92     // Check that run methods do nothing
93     ft.run();
94 jsr166 1.37 if (f instanceof PublicFutureTask) {
95     PublicFutureTask pf = (PublicFutureTask) f;
96     int savedRunCount = pf.runCount();
97     pf.run();
98     assertFalse(pf.runAndReset());
99     assertEquals(savedRunCount, pf.runCount());
100     }
101 jsr166 1.29 checkNotDone(f);
102     }
103 jsr166 1.22 }
104    
105     <T> void checkCompletedNormally(Future<T> f, T expected) {
106 jsr166 1.29 checkIsDone(f);
107 jsr166 1.22 assertFalse(f.isCancelled());
108    
109     try {
110     assertSame(expected, f.get());
111     } catch (Throwable fail) { threadUnexpectedException(fail); }
112     try {
113     assertSame(expected, f.get(5L, SECONDS));
114     } catch (Throwable fail) { threadUnexpectedException(fail); }
115     }
116    
117     void checkCancelled(Future<?> f) {
118 jsr166 1.29 checkIsDone(f);
119 jsr166 1.22 assertTrue(f.isCancelled());
120    
121     try {
122     f.get();
123     shouldThrow();
124     } catch (CancellationException success) {
125     } catch (Throwable fail) { threadUnexpectedException(fail); }
126    
127     try {
128     f.get(5L, SECONDS);
129     shouldThrow();
130     } catch (CancellationException success) {
131     } catch (Throwable fail) { threadUnexpectedException(fail); }
132 jsr166 1.29 }
133 jsr166 1.22
134 jsr166 1.29 void tryToConfuseDoneTask(PublicFutureTask pf) {
135     pf.set(new Object());
136     pf.setException(new Error());
137     for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
138 jsr166 1.41 pf.cancel(mayInterruptIfRunning);
139 jsr166 1.29 }
140 jsr166 1.22 }
141    
142     void checkCompletedAbnormally(Future<?> f, Throwable t) {
143 jsr166 1.29 checkIsDone(f);
144 jsr166 1.22 assertFalse(f.isCancelled());
145    
146     try {
147     f.get();
148     shouldThrow();
149     } catch (ExecutionException success) {
150     assertSame(t, success.getCause());
151     } catch (Throwable fail) { threadUnexpectedException(fail); }
152    
153     try {
154     f.get(5L, SECONDS);
155     shouldThrow();
156     } catch (ExecutionException success) {
157     assertSame(t, success.getCause());
158     } catch (Throwable fail) { threadUnexpectedException(fail); }
159     }
160    
161 dl 1.4 /**
162     * Subclass to expose protected methods
163     */
164 dl 1.7 static class PublicFutureTask extends FutureTask {
165 jsr166 1.29 private final AtomicInteger runCount;
166     private final AtomicInteger doneCount = new AtomicInteger(0);
167     private final AtomicInteger runAndResetCount = new AtomicInteger(0);
168     private final AtomicInteger setCount = new AtomicInteger(0);
169     private final AtomicInteger setExceptionCount = new AtomicInteger(0);
170     public int runCount() { return runCount.get(); }
171     public int doneCount() { return doneCount.get(); }
172     public int runAndResetCount() { return runAndResetCount.get(); }
173     public int setCount() { return setCount.get(); }
174     public int setExceptionCount() { return setExceptionCount.get(); }
175    
176     PublicFutureTask(Runnable runnable) {
177     this(runnable, seven);
178     }
179     PublicFutureTask(Runnable runnable, Object result) {
180     this(runnable, result, new AtomicInteger(0));
181     }
182     private PublicFutureTask(final Runnable runnable, Object result,
183     final AtomicInteger runCount) {
184     super(new Runnable() {
185 jsr166 1.31 public void run() {
186     runCount.getAndIncrement();
187     runnable.run();
188     }}, result);
189 jsr166 1.29 this.runCount = runCount;
190     }
191     PublicFutureTask(Callable callable) {
192     this(callable, new AtomicInteger(0));
193     }
194     private PublicFutureTask(final Callable callable,
195     final AtomicInteger runCount) {
196     super(new Callable() {
197     public Object call() throws Exception {
198     runCount.getAndIncrement();
199     return callable.call();
200     }});
201     this.runCount = runCount;
202     }
203 jsr166 1.30 @Override public void done() {
204 jsr166 1.29 assertTrue(isDone());
205     doneCount.incrementAndGet();
206     super.done();
207     }
208 jsr166 1.30 @Override public boolean runAndReset() {
209 jsr166 1.29 runAndResetCount.incrementAndGet();
210     return super.runAndReset();
211     }
212 jsr166 1.30 @Override public void set(Object x) {
213 jsr166 1.29 setCount.incrementAndGet();
214     super.set(x);
215     }
216 jsr166 1.30 @Override public void setException(Throwable t) {
217 jsr166 1.29 setExceptionCount.incrementAndGet();
218     super.setException(t);
219     }
220     }
221    
222     class Counter extends CheckedRunnable {
223     final AtomicInteger count = new AtomicInteger(0);
224     public int get() { return count.get(); }
225     public void realRun() {
226     count.getAndIncrement();
227     }
228 dl 1.4 }
229 dl 1.1
230 dl 1.5 /**
231 jsr166 1.29 * creating a future with a null callable throws NullPointerException
232 dl 1.5 */
233     public void testConstructor() {
234 dl 1.3 try {
235 jsr166 1.29 new FutureTask(null);
236 jsr166 1.17 shouldThrow();
237 jsr166 1.15 } catch (NullPointerException success) {}
238 dl 1.3 }
239    
240 dl 1.5 /**
241 jsr166 1.29 * creating a future with null runnable throws NullPointerException
242 dl 1.5 */
243     public void testConstructor2() {
244 dl 1.3 try {
245 jsr166 1.29 new FutureTask(null, Boolean.TRUE);
246 jsr166 1.17 shouldThrow();
247 jsr166 1.15 } catch (NullPointerException success) {}
248 dl 1.3 }
249    
250 dl 1.5 /**
251 dl 1.6 * isDone is true when a task completes
252 dl 1.5 */
253     public void testIsDone() {
254 jsr166 1.29 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
255     assertFalse(task.isDone());
256 jsr166 1.16 task.run();
257     assertTrue(task.isDone());
258 jsr166 1.22 checkCompletedNormally(task, Boolean.TRUE);
259 jsr166 1.29 assertEquals(1, task.runCount());
260 dl 1.4 }
261    
262 dl 1.5 /**
263 dl 1.9 * runAndReset of a non-cancelled task succeeds
264 dl 1.5 */
265 dl 1.9 public void testRunAndReset() {
266 dl 1.7 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
267 jsr166 1.29 for (int i = 0; i < 3; i++) {
268     assertTrue(task.runAndReset());
269     checkNotDone(task);
270 jsr166 1.44 assertEquals(i + 1, task.runCount());
271     assertEquals(i + 1, task.runAndResetCount());
272 jsr166 1.29 assertEquals(0, task.setCount());
273     assertEquals(0, task.setExceptionCount());
274     }
275 dl 1.4 }
276    
277 dl 1.5 /**
278 dl 1.9 * runAndReset after cancellation fails
279 dl 1.5 */
280 jsr166 1.29 public void testRunAndResetAfterCancel() {
281     for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
282     PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
283     assertTrue(task.cancel(mayInterruptIfRunning));
284     for (int i = 0; i < 3; i++) {
285     assertFalse(task.runAndReset());
286     assertEquals(0, task.runCount());
287 jsr166 1.44 assertEquals(i + 1, task.runAndResetCount());
288 jsr166 1.29 assertEquals(0, task.setCount());
289     assertEquals(0, task.setExceptionCount());
290     }
291     tryToConfuseDoneTask(task);
292     checkCancelled(task);
293     }
294 dl 1.4 }
295    
296 dl 1.5 /**
297 dl 1.11 * setting value causes get to return it
298 dl 1.5 */
299 jsr166 1.15 public void testSet() throws Exception {
300 dl 1.7 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
301 dl 1.4 task.set(one);
302 jsr166 1.29 for (int i = 0; i < 3; i++) {
303     assertSame(one, task.get());
304     assertSame(one, task.get(LONG_DELAY_MS, MILLISECONDS));
305     assertEquals(1, task.setCount());
306     }
307     tryToConfuseDoneTask(task);
308 jsr166 1.22 checkCompletedNormally(task, one);
309 jsr166 1.29 assertEquals(0, task.runCount());
310 dl 1.4 }
311    
312 dl 1.5 /**
313 dl 1.6 * setException causes get to throw ExecutionException
314 dl 1.5 */
315 jsr166 1.29 public void testSetException_get() throws Exception {
316 dl 1.4 Exception nse = new NoSuchElementException();
317 dl 1.7 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
318 dl 1.4 task.setException(nse);
319 jsr166 1.29
320     try {
321     task.get();
322     shouldThrow();
323     } catch (ExecutionException success) {
324     assertSame(nse, success.getCause());
325     checkCompletedAbnormally(task, nse);
326     }
327    
328 dl 1.4 try {
329 jsr166 1.29 task.get(LONG_DELAY_MS, MILLISECONDS);
330 jsr166 1.17 shouldThrow();
331 jsr166 1.15 } catch (ExecutionException success) {
332 jsr166 1.29 assertSame(nse, success.getCause());
333 jsr166 1.22 checkCompletedAbnormally(task, nse);
334 dl 1.4 }
335 jsr166 1.29
336     assertEquals(1, task.setExceptionCount());
337     assertEquals(0, task.setCount());
338     tryToConfuseDoneTask(task);
339     checkCompletedAbnormally(task, nse);
340     assertEquals(0, task.runCount());
341 dl 1.4 }
342    
343 dl 1.5 /**
344 jsr166 1.29 * cancel(false) before run succeeds
345 dl 1.5 */
346 dl 1.1 public void testCancelBeforeRun() {
347 jsr166 1.29 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
348 dl 1.1 assertTrue(task.cancel(false));
349 jsr166 1.16 task.run();
350 jsr166 1.32 assertEquals(0, task.runCount());
351 jsr166 1.29 assertEquals(0, task.setCount());
352     assertEquals(0, task.setExceptionCount());
353 jsr166 1.32 assertTrue(task.isCancelled());
354     assertTrue(task.isDone());
355 jsr166 1.29 tryToConfuseDoneTask(task);
356 jsr166 1.32 assertEquals(0, task.runCount());
357 jsr166 1.22 checkCancelled(task);
358 dl 1.1 }
359    
360 dl 1.5 /**
361 jsr166 1.29 * cancel(true) before run succeeds
362 dl 1.5 */
363 dl 1.1 public void testCancelBeforeRun2() {
364 jsr166 1.29 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
365 dl 1.1 assertTrue(task.cancel(true));
366 jsr166 1.16 task.run();
367 jsr166 1.32 assertEquals(0, task.runCount());
368 jsr166 1.29 assertEquals(0, task.setCount());
369     assertEquals(0, task.setExceptionCount());
370 jsr166 1.32 assertTrue(task.isCancelled());
371     assertTrue(task.isDone());
372 jsr166 1.29 tryToConfuseDoneTask(task);
373 jsr166 1.32 assertEquals(0, task.runCount());
374 jsr166 1.22 checkCancelled(task);
375 dl 1.1 }
376    
377 dl 1.5 /**
378 jsr166 1.29 * cancel(false) of a completed task fails
379 dl 1.5 */
380 dl 1.1 public void testCancelAfterRun() {
381 jsr166 1.29 PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
382 jsr166 1.16 task.run();
383 dl 1.1 assertFalse(task.cancel(false));
384 jsr166 1.32 assertEquals(1, task.runCount());
385 jsr166 1.29 assertEquals(1, task.setCount());
386     assertEquals(0, task.setExceptionCount());
387     tryToConfuseDoneTask(task);
388     checkCompletedNormally(task, Boolean.TRUE);
389     assertEquals(1, task.runCount());
390     }
391    
392     /**
393     * cancel(true) of a completed task fails
394     */
395     public void testCancelAfterRun2() {
396     PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
397     task.run();
398     assertFalse(task.cancel(true));
399 jsr166 1.32 assertEquals(1, task.runCount());
400 jsr166 1.29 assertEquals(1, task.setCount());
401     assertEquals(0, task.setExceptionCount());
402     tryToConfuseDoneTask(task);
403 jsr166 1.22 checkCompletedNormally(task, Boolean.TRUE);
404 jsr166 1.29 assertEquals(1, task.runCount());
405 dl 1.1 }
406    
407 dl 1.5 /**
408 jsr166 1.29 * cancel(true) interrupts a running task that subsequently succeeds
409 dl 1.5 */
410 jsr166 1.29 public void testCancelInterrupt() {
411     final CountDownLatch pleaseCancel = new CountDownLatch(1);
412     final PublicFutureTask task =
413     new PublicFutureTask(new CheckedRunnable() {
414     public void realRun() {
415     pleaseCancel.countDown();
416     try {
417     delay(LONG_DELAY_MS);
418     shouldThrow();
419     } catch (InterruptedException success) {}
420 jsr166 1.15 }});
421    
422 jsr166 1.22 Thread t = newStartedThread(task);
423 jsr166 1.29 await(pleaseCancel);
424 jsr166 1.15 assertTrue(task.cancel(true));
425 jsr166 1.29 assertTrue(task.isCancelled());
426 jsr166 1.32 assertTrue(task.isDone());
427 jsr166 1.29 awaitTermination(t);
428     assertEquals(1, task.runCount());
429     assertEquals(1, task.setCount());
430     assertEquals(0, task.setExceptionCount());
431     tryToConfuseDoneTask(task);
432 jsr166 1.22 checkCancelled(task);
433 jsr166 1.29 }
434    
435     /**
436 jsr166 1.33 * cancel(true) tries to interrupt a running task, but
437     * Thread.interrupt throws (simulating a restrictive security
438     * manager)
439 jsr166 1.32 */
440     public void testCancelInterrupt_ThrowsSecurityException() {
441     final CountDownLatch pleaseCancel = new CountDownLatch(1);
442     final CountDownLatch cancelled = new CountDownLatch(1);
443     final PublicFutureTask task =
444     new PublicFutureTask(new CheckedRunnable() {
445     public void realRun() {
446     pleaseCancel.countDown();
447     await(cancelled);
448     assertFalse(Thread.interrupted());
449     }});
450    
451 jsr166 1.33 final Thread t = new Thread(task) {
452     // Simulate a restrictive security manager.
453     @Override public void interrupt() {
454     throw new SecurityException();
455     }};
456     t.setDaemon(true);
457     t.start();
458    
459 jsr166 1.32 await(pleaseCancel);
460     try {
461 jsr166 1.33 task.cancel(true);
462     shouldThrow();
463     } catch (SecurityException expected) {}
464    
465     // We failed to deliver the interrupt, but the world retains
466     // its sanity, as if we had done task.cancel(false)
467 jsr166 1.32 assertTrue(task.isCancelled());
468     assertTrue(task.isDone());
469     assertEquals(1, task.runCount());
470     assertEquals(1, task.doneCount());
471     assertEquals(0, task.setCount());
472     assertEquals(0, task.setExceptionCount());
473     cancelled.countDown();
474     awaitTermination(t);
475     assertEquals(1, task.setCount());
476     assertEquals(0, task.setExceptionCount());
477     tryToConfuseDoneTask(task);
478     checkCancelled(task);
479     }
480    
481     /**
482 jsr166 1.29 * cancel(true) interrupts a running task that subsequently throws
483     */
484     public void testCancelInterrupt_taskFails() {
485     final CountDownLatch pleaseCancel = new CountDownLatch(1);
486     final PublicFutureTask task =
487     new PublicFutureTask(new Runnable() {
488     public void run() {
489 jsr166 1.42 pleaseCancel.countDown();
490 jsr166 1.29 try {
491     delay(LONG_DELAY_MS);
492 jsr166 1.38 threadShouldThrow();
493     } catch (InterruptedException success) {
494     } catch (Throwable t) { threadUnexpectedException(t); }
495 jsr166 1.35 throw new RuntimeException();
496 jsr166 1.29 }});
497    
498     Thread t = newStartedThread(task);
499     await(pleaseCancel);
500     assertTrue(task.cancel(true));
501     assertTrue(task.isCancelled());
502     awaitTermination(t);
503     assertEquals(1, task.runCount());
504     assertEquals(0, task.setCount());
505     assertEquals(1, task.setExceptionCount());
506     tryToConfuseDoneTask(task);
507 jsr166 1.22 checkCancelled(task);
508 dl 1.1 }
509    
510 dl 1.5 /**
511 dl 1.6 * cancel(false) does not interrupt a running task
512 dl 1.5 */
513 jsr166 1.29 public void testCancelNoInterrupt() {
514     final CountDownLatch pleaseCancel = new CountDownLatch(1);
515 jsr166 1.22 final CountDownLatch cancelled = new CountDownLatch(1);
516 jsr166 1.29 final PublicFutureTask task =
517     new PublicFutureTask(new CheckedCallable<Boolean>() {
518     public Boolean realCall() {
519     pleaseCancel.countDown();
520     await(cancelled);
521 jsr166 1.22 assertFalse(Thread.interrupted());
522 dl 1.1 return Boolean.TRUE;
523 jsr166 1.15 }});
524    
525 jsr166 1.22 Thread t = newStartedThread(task);
526 jsr166 1.29 await(pleaseCancel);
527 jsr166 1.15 assertTrue(task.cancel(false));
528 jsr166 1.29 assertTrue(task.isCancelled());
529 jsr166 1.22 cancelled.countDown();
530 jsr166 1.29 awaitTermination(t);
531     assertEquals(1, task.runCount());
532     assertEquals(1, task.setCount());
533     assertEquals(0, task.setExceptionCount());
534     tryToConfuseDoneTask(task);
535 jsr166 1.22 checkCancelled(task);
536 dl 1.1 }
537    
538 dl 1.5 /**
539 jsr166 1.23 * run in one thread causes get in another thread to retrieve value
540 dl 1.5 */
541 jsr166 1.29 public void testGetRun() {
542     final CountDownLatch pleaseRun = new CountDownLatch(2);
543 jsr166 1.23
544     final PublicFutureTask task =
545     new PublicFutureTask(new CheckedCallable<Object>() {
546 jsr166 1.29 public Object realCall() {
547     return two;
548 jsr166 1.23 }});
549    
550 jsr166 1.29 Thread t1 = newStartedThread(new CheckedRunnable() {
551 jsr166 1.23 public void realRun() throws Exception {
552 jsr166 1.29 pleaseRun.countDown();
553     assertSame(two, task.get());
554 jsr166 1.23 }});
555    
556 jsr166 1.29 Thread t2 = newStartedThread(new CheckedRunnable() {
557 jsr166 1.15 public void realRun() throws Exception {
558 jsr166 1.29 pleaseRun.countDown();
559     assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
560 jsr166 1.15 }});
561 jsr166 1.12
562 jsr166 1.29 await(pleaseRun);
563 jsr166 1.23 checkNotDone(task);
564 jsr166 1.29 assertTrue(t1.isAlive());
565     assertTrue(t2.isAlive());
566 jsr166 1.22 task.run();
567 jsr166 1.29 checkCompletedNormally(task, two);
568     assertEquals(1, task.runCount());
569     assertEquals(1, task.setCount());
570     assertEquals(0, task.setExceptionCount());
571     awaitTermination(t1);
572     awaitTermination(t2);
573     tryToConfuseDoneTask(task);
574     checkCompletedNormally(task, two);
575 dl 1.1 }
576    
577 dl 1.5 /**
578 jsr166 1.29 * set in one thread causes get in another thread to retrieve value
579 jsr166 1.23 */
580 jsr166 1.29 public void testGetSet() {
581     final CountDownLatch pleaseSet = new CountDownLatch(2);
582 jsr166 1.23
583     final PublicFutureTask task =
584     new PublicFutureTask(new CheckedCallable<Object>() {
585     public Object realCall() throws InterruptedException {
586 jsr166 1.29 return two;
587 jsr166 1.23 }});
588    
589 jsr166 1.29 Thread t1 = newStartedThread(new CheckedRunnable() {
590     public void realRun() throws Exception {
591     pleaseSet.countDown();
592     assertSame(two, task.get());
593     }});
594    
595     Thread t2 = newStartedThread(new CheckedRunnable() {
596 jsr166 1.23 public void realRun() throws Exception {
597 jsr166 1.29 pleaseSet.countDown();
598     assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
599 jsr166 1.23 }});
600    
601 jsr166 1.29 await(pleaseSet);
602 jsr166 1.23 checkNotDone(task);
603 jsr166 1.29 assertTrue(t1.isAlive());
604     assertTrue(t2.isAlive());
605     task.set(two);
606     assertEquals(0, task.runCount());
607     assertEquals(1, task.setCount());
608     assertEquals(0, task.setExceptionCount());
609     tryToConfuseDoneTask(task);
610     checkCompletedNormally(task, two);
611     awaitTermination(t1);
612     awaitTermination(t2);
613 jsr166 1.23 }
614    
615     /**
616 jsr166 1.21 * Cancelling a task causes timed get in another thread to throw
617     * CancellationException
618 dl 1.5 */
619 jsr166 1.29 public void testTimedGet_Cancellation() {
620 jsr166 1.36 testTimedGet_Cancellation(false);
621     }
622     public void testTimedGet_Cancellation_interrupt() {
623     testTimedGet_Cancellation(true);
624     }
625     public void testTimedGet_Cancellation(final boolean mayInterruptIfRunning) {
626     final CountDownLatch pleaseCancel = new CountDownLatch(3);
627     final CountDownLatch cancelled = new CountDownLatch(1);
628     final Callable<Object> callable =
629     new CheckedCallable<Object>() {
630     public Object realCall() throws InterruptedException {
631     pleaseCancel.countDown();
632     if (mayInterruptIfRunning) {
633     try {
634     delay(2*LONG_DELAY_MS);
635     } catch (InterruptedException success) {}
636     } else {
637     await(cancelled);
638     }
639     return two;
640     }};
641     final PublicFutureTask task = new PublicFutureTask(callable);
642 jsr166 1.29
643 jsr166 1.36 Thread t1 = new ThreadShouldThrow(CancellationException.class) {
644 jsr166 1.29 public void realRun() throws Exception {
645     pleaseCancel.countDown();
646     task.get();
647     }};
648 jsr166 1.36 Thread t2 = new ThreadShouldThrow(CancellationException.class) {
649 jsr166 1.29 public void realRun() throws Exception {
650     pleaseCancel.countDown();
651     task.get(2*LONG_DELAY_MS, MILLISECONDS);
652     }};
653 jsr166 1.36 t1.start();
654     t2.start();
655     Thread t3 = newStartedThread(task);
656     await(pleaseCancel);
657     checkIsRunning(task);
658     task.cancel(mayInterruptIfRunning);
659     checkCancelled(task);
660     awaitTermination(t1);
661     awaitTermination(t2);
662     cancelled.countDown();
663     awaitTermination(t3);
664     assertEquals(1, task.runCount());
665     assertEquals(1, task.setCount());
666     assertEquals(0, task.setExceptionCount());
667     tryToConfuseDoneTask(task);
668     checkCancelled(task);
669 dl 1.1 }
670 jsr166 1.12
671 dl 1.5 /**
672 dl 1.6 * A runtime exception in task causes get to throw ExecutionException
673 dl 1.5 */
674 jsr166 1.15 public void testGet_ExecutionException() throws InterruptedException {
675 jsr166 1.29 final ArithmeticException e = new ArithmeticException();
676     final PublicFutureTask task = new PublicFutureTask(new Callable() {
677 jsr166 1.16 public Object call() {
678 jsr166 1.29 throw e;
679 jsr166 1.15 }});
680    
681 jsr166 1.22 task.run();
682 jsr166 1.29 assertEquals(1, task.runCount());
683     assertEquals(0, task.setCount());
684     assertEquals(1, task.setExceptionCount());
685 jsr166 1.15 try {
686 jsr166 1.22 task.get();
687 jsr166 1.17 shouldThrow();
688 jsr166 1.16 } catch (ExecutionException success) {
689 jsr166 1.29 assertSame(e, success.getCause());
690     tryToConfuseDoneTask(task);
691 jsr166 1.22 checkCompletedAbnormally(task, success.getCause());
692 dl 1.1 }
693     }
694 jsr166 1.12
695 dl 1.5 /**
696 jsr166 1.20 * A runtime exception in task causes timed get to throw ExecutionException
697 dl 1.5 */
698 jsr166 1.15 public void testTimedGet_ExecutionException2() throws Exception {
699 jsr166 1.29 final ArithmeticException e = new ArithmeticException();
700     final PublicFutureTask task = new PublicFutureTask(new Callable() {
701 jsr166 1.16 public Object call() {
702 jsr166 1.29 throw e;
703 jsr166 1.15 }});
704    
705 jsr166 1.22 task.run();
706 jsr166 1.16 try {
707 jsr166 1.29 task.get(LONG_DELAY_MS, MILLISECONDS);
708 jsr166 1.17 shouldThrow();
709 jsr166 1.16 } catch (ExecutionException success) {
710 jsr166 1.29 assertSame(e, success.getCause());
711     tryToConfuseDoneTask(task);
712 jsr166 1.22 checkCompletedAbnormally(task, success.getCause());
713 jsr166 1.15 }
714 dl 1.1 }
715 jsr166 1.12
716 dl 1.5 /**
717 jsr166 1.29 * get is interruptible
718 dl 1.5 */
719 jsr166 1.29 public void testGet_interruptible() {
720     final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
721 jsr166 1.22 final FutureTask task = new FutureTask(new NoOpCallable());
722 jsr166 1.29 Thread t = newStartedThread(new CheckedRunnable() {
723 jsr166 1.15 public void realRun() throws Exception {
724 jsr166 1.29 Thread.currentThread().interrupt();
725     try {
726     task.get();
727     shouldThrow();
728     } catch (InterruptedException success) {}
729     assertFalse(Thread.interrupted());
730    
731     pleaseInterrupt.countDown();
732     try {
733     task.get();
734     shouldThrow();
735     } catch (InterruptedException success) {}
736     assertFalse(Thread.interrupted());
737 jsr166 1.15 }});
738    
739 jsr166 1.29 await(pleaseInterrupt);
740 jsr166 1.15 t.interrupt();
741 jsr166 1.28 awaitTermination(t);
742 jsr166 1.22 checkNotDone(task);
743 dl 1.1 }
744    
745 dl 1.5 /**
746 jsr166 1.29 * timed get is interruptible
747 dl 1.5 */
748 jsr166 1.29 public void testTimedGet_interruptible() {
749     final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
750 jsr166 1.22 final FutureTask task = new FutureTask(new NoOpCallable());
751 jsr166 1.29 Thread t = newStartedThread(new CheckedRunnable() {
752 jsr166 1.15 public void realRun() throws Exception {
753 jsr166 1.29 Thread.currentThread().interrupt();
754     try {
755     task.get(2*LONG_DELAY_MS, MILLISECONDS);
756     shouldThrow();
757     } catch (InterruptedException success) {}
758     assertFalse(Thread.interrupted());
759    
760     pleaseInterrupt.countDown();
761     try {
762     task.get(2*LONG_DELAY_MS, MILLISECONDS);
763     shouldThrow();
764     } catch (InterruptedException success) {}
765     assertFalse(Thread.interrupted());
766 jsr166 1.15 }});
767    
768 jsr166 1.29 await(pleaseInterrupt);
769 jsr166 1.15 t.interrupt();
770 jsr166 1.28 awaitTermination(t);
771 jsr166 1.22 checkNotDone(task);
772 dl 1.1 }
773 jsr166 1.12
774 dl 1.5 /**
775 dl 1.6 * A timed out timed get throws TimeoutException
776 dl 1.5 */
777 jsr166 1.15 public void testGet_TimeoutException() throws Exception {
778 jsr166 1.29 FutureTask task = new FutureTask(new NoOpCallable());
779     long startTime = System.nanoTime();
780 jsr166 1.16 try {
781 jsr166 1.29 task.get(timeoutMillis(), MILLISECONDS);
782 jsr166 1.17 shouldThrow();
783 jsr166 1.29 } catch (TimeoutException success) {
784     assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
785     }
786     }
787    
788     /**
789     * timed get with null TimeUnit throws NullPointerException
790     */
791     public void testGet_NullTimeUnit() throws Exception {
792     FutureTask task = new FutureTask(new NoOpCallable());
793     long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
794    
795     for (long timeout : timeouts) {
796     try {
797     task.get(timeout, null);
798     shouldThrow();
799     } catch (NullPointerException success) {}
800     }
801    
802     task.run();
803    
804     for (long timeout : timeouts) {
805     try {
806     task.get(timeout, null);
807     shouldThrow();
808     } catch (NullPointerException success) {}
809     }
810 dl 1.1 }
811 jsr166 1.12
812 jsr166 1.39 /**
813     * timed get with most negative timeout works correctly (i.e. no
814     * underflow bug)
815     */
816     public void testGet_NegativeInfinityTimeout() throws Exception {
817     final ExecutorService pool = Executors.newFixedThreadPool(10);
818     final Runnable nop = new Runnable() { public void run() {}};
819     final FutureTask<Void> task = new FutureTask<>(nop, null);
820     final List<Future<?>> futures = new ArrayList<>();
821     Runnable r = new Runnable() { public void run() {
822     for (long timeout : new long[] { 0L, -1L, Long.MIN_VALUE }) {
823     try {
824     task.get(timeout, NANOSECONDS);
825     shouldThrow();
826     } catch (TimeoutException success) {
827     } catch (Throwable fail) {threadUnexpectedException(fail);}}}};
828     for (int i = 0; i < 10; i++)
829     futures.add(pool.submit(r));
830     try {
831     joinPool(pool);
832     for (Future<?> future : futures)
833     checkCompletedNormally(future, null);
834     } finally {
835     task.run(); // last resort to help terminate
836     }
837     }
838    
839 dl 1.1 }