[cvs] / jsr166 / src / test / tck / FutureTaskTest.java Repository:
ViewVC logotype

Annotation of /jsr166/src/test/tck/FutureTaskTest.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.42 - (view) (download)

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.19 junit.textui.TestRunner.run(suite());
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 :     assertEquals(i+1, task.runCount());
271 :     assertEquals(i+1, task.runAndResetCount());
272 :     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 :     assertEquals(i+1, task.runAndResetCount());
288 :     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 }

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8