ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/FutureTaskTest.java
Revision: 1.37
Committed: Sun Apr 21 06:54:11 2013 UTC (11 years ago) by jsr166
Branch: MAIN
Changes since 1.36: +26 -6 lines
Log Message:
fix rare failure in testTimedGet_Cancellation_interrupt

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