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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.19, Wed Aug 25 00:07:03 2010 UTC revision 1.42, Sat Feb 28 18:18:56 2015 UTC
# Line 1  Line 1 
1  /*  /*
2   * Written by Doug Lea with assistance from members of JCP JSR-166   * Written by Doug Lea with assistance from members of JCP JSR-166
3   * Expert Group and released to the public domain, as explained at   * Expert Group and released to the public domain, as explained at
4   * http://creativecommons.org/licenses/publicdomain   * http://creativecommons.org/publicdomain/zero/1.0/
5   * Other contributors include Andrew Wright, Jeffrey Hayes,   * Other contributors include Andrew Wright, Jeffrey Hayes,
6   * Pat Fisher, Mike Judd.   * Pat Fisher, Mike Judd.
7   */   */
8    
 import junit.framework.*;  
 import java.util.concurrent.*;  
9  import static java.util.concurrent.TimeUnit.MILLISECONDS;  import static java.util.concurrent.TimeUnit.MILLISECONDS;
10  import java.util.*;  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    import java.util.concurrent.Callable;
17    import java.util.concurrent.CancellationException;
18    import java.util.concurrent.CountDownLatch;
19    import java.util.concurrent.ExecutionException;
20    import java.util.concurrent.Executors;
21    import java.util.concurrent.ExecutorService;
22    import java.util.concurrent.Future;
23    import java.util.concurrent.FutureTask;
24    import java.util.concurrent.TimeoutException;
25    import java.util.concurrent.atomic.AtomicInteger;
26    
27    import junit.framework.Test;
28    import junit.framework.TestSuite;
29    
30  public class FutureTaskTest extends JSR166TestCase {  public class FutureTaskTest extends JSR166TestCase {
31    
# Line 20  Line 36 
36          return new TestSuite(FutureTaskTest.class);          return new TestSuite(FutureTaskTest.class);
37      }      }
38    
39        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                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    
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                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                assertTrue(f.isDone());
74            }
75        }
76    
77        void checkNotDone(Future<?> f) {
78            assertFalse(f.isDone());
79            assertFalse(f.isCancelled());
80            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                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                checkNotDone(f);
102            }
103        }
104    
105        <T> void checkCompletedNormally(Future<T> f, T expected) {
106            checkIsDone(f);
107            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            checkIsDone(f);
119            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        }
133    
134        void tryToConfuseDoneTask(PublicFutureTask pf) {
135            pf.set(new Object());
136            pf.setException(new Error());
137            for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
138                pf.cancel(mayInterruptIfRunning);
139            }
140        }
141    
142        void checkCompletedAbnormally(Future<?> f, Throwable t) {
143            checkIsDone(f);
144            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      /**      /**
162       * Subclass to expose protected methods       * Subclass to expose protected methods
163       */       */
164      static class PublicFutureTask extends FutureTask {      static class PublicFutureTask extends FutureTask {
165          public PublicFutureTask(Callable r) { super(r); }          private final AtomicInteger runCount;
166          public boolean runAndReset() { return super.runAndReset(); }          private final AtomicInteger doneCount = new AtomicInteger(0);
167          public void set(Object x) { super.set(x); }          private final AtomicInteger runAndResetCount = new AtomicInteger(0);
168          public void setException(Throwable t) { super.setException(t); }          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                    public void run() {
186                        runCount.getAndIncrement();
187                        runnable.run();
188                    }}, result);
189                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            @Override public void done() {
204                assertTrue(isDone());
205                doneCount.incrementAndGet();
206                super.done();
207            }
208            @Override public boolean runAndReset() {
209                runAndResetCount.incrementAndGet();
210                return super.runAndReset();
211            }
212            @Override public void set(Object x) {
213                setCount.incrementAndGet();
214                super.set(x);
215            }
216            @Override public void setException(Throwable t) {
217                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      }      }
229    
230      /**      /**
231       * Creating a future with a null callable throws NPE       * creating a future with a null callable throws NullPointerException
232       */       */
233      public void testConstructor() {      public void testConstructor() {
234          try {          try {
235              FutureTask task = new FutureTask(null);              new FutureTask(null);
236              shouldThrow();              shouldThrow();
237          } catch (NullPointerException success) {}          } catch (NullPointerException success) {}
238      }      }
239    
240      /**      /**
241       * creating a future with null runnable fails       * creating a future with null runnable throws NullPointerException
242       */       */
243      public void testConstructor2() {      public void testConstructor2() {
244          try {          try {
245              FutureTask task = new FutureTask(null, Boolean.TRUE);              new FutureTask(null, Boolean.TRUE);
246              shouldThrow();              shouldThrow();
247          } catch (NullPointerException success) {}          } catch (NullPointerException success) {}
248      }      }
# Line 54  Line 251 
251       * isDone is true when a task completes       * isDone is true when a task completes
252       */       */
253      public void testIsDone() {      public void testIsDone() {
254          FutureTask task = new FutureTask(new NoOpCallable());          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
255            assertFalse(task.isDone());
256          task.run();          task.run();
257          assertTrue(task.isDone());          assertTrue(task.isDone());
258          assertFalse(task.isCancelled());          checkCompletedNormally(task, Boolean.TRUE);
259            assertEquals(1, task.runCount());
260      }      }
261    
262      /**      /**
# Line 65  Line 264 
264       */       */
265      public void testRunAndReset() {      public void testRunAndReset() {
266          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
267            for (int i = 0; i < 3; i++) {
268          assertTrue(task.runAndReset());          assertTrue(task.runAndReset());
269          assertFalse(task.isDone());              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      }      }
276    
277      /**      /**
278       * runAndReset after cancellation fails       * runAndReset after cancellation fails
279       */       */
280      public void testResetAfterCancel() {      public void testRunAndResetAfterCancel() {
281            for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
282          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
283          assertTrue(task.cancel(false));              assertTrue(task.cancel(mayInterruptIfRunning));
284                for (int i = 0; i < 3; i++) {
285          assertFalse(task.runAndReset());          assertFalse(task.runAndReset());
286          assertTrue(task.isDone());                  assertEquals(0, task.runCount());
287          assertTrue(task.isCancelled());                  assertEquals(i+1, task.runAndResetCount());
288                    assertEquals(0, task.setCount());
289                    assertEquals(0, task.setExceptionCount());
290                }
291                tryToConfuseDoneTask(task);
292                checkCancelled(task);
293            }
294      }      }
   
   
295    
296      /**      /**
297       * setting value causes get to return it       * setting value causes get to return it
# Line 88  Line 299 
299      public void testSet() throws Exception {      public void testSet() throws Exception {
300          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
301          task.set(one);          task.set(one);
302          assertSame(task.get(), one);          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            checkCompletedNormally(task, one);
309            assertEquals(0, task.runCount());
310      }      }
311    
312      /**      /**
313       * setException causes get to throw ExecutionException       * setException causes get to throw ExecutionException
314       */       */
315      public void testSetException() throws Exception {      public void testSetException_get() throws Exception {
316          Exception nse = new NoSuchElementException();          Exception nse = new NoSuchElementException();
317          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
318          task.setException(nse);          task.setException(nse);
319    
320            try {
321                task.get();
322                shouldThrow();
323            } catch (ExecutionException success) {
324                assertSame(nse, success.getCause());
325                checkCompletedAbnormally(task, nse);
326            }
327    
328          try {          try {
329              Object x = task.get();              task.get(LONG_DELAY_MS, MILLISECONDS);
330              shouldThrow();              shouldThrow();
331          } catch (ExecutionException success) {          } catch (ExecutionException success) {
332              assertSame(success.getCause(), nse);              assertSame(nse, success.getCause());
333                checkCompletedAbnormally(task, nse);
334          }          }
335    
336            assertEquals(1, task.setExceptionCount());
337            assertEquals(0, task.setCount());
338            tryToConfuseDoneTask(task);
339            checkCompletedAbnormally(task, nse);
340            assertEquals(0, task.runCount());
341      }      }
342    
343      /**      /**
344       *  Cancelling before running succeeds       * cancel(false) before run succeeds
345       */       */
346      public void testCancelBeforeRun() {      public void testCancelBeforeRun() {
347          FutureTask task = new FutureTask(new NoOpCallable());          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
348          assertTrue(task.cancel(false));          assertTrue(task.cancel(false));
349          task.run();          task.run();
350          assertTrue(task.isDone());          assertEquals(0, task.runCount());
351            assertEquals(0, task.setCount());
352            assertEquals(0, task.setExceptionCount());
353          assertTrue(task.isCancelled());          assertTrue(task.isCancelled());
354            assertTrue(task.isDone());
355            tryToConfuseDoneTask(task);
356            assertEquals(0, task.runCount());
357            checkCancelled(task);
358      }      }
359    
360      /**      /**
361       * Cancel(true) before run succeeds       * cancel(true) before run succeeds
362       */       */
363      public void testCancelBeforeRun2() {      public void testCancelBeforeRun2() {
364          FutureTask task = new FutureTask(new NoOpCallable());          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
365          assertTrue(task.cancel(true));          assertTrue(task.cancel(true));
366          task.run();          task.run();
367          assertTrue(task.isDone());          assertEquals(0, task.runCount());
368            assertEquals(0, task.setCount());
369            assertEquals(0, task.setExceptionCount());
370          assertTrue(task.isCancelled());          assertTrue(task.isCancelled());
371            assertTrue(task.isDone());
372            tryToConfuseDoneTask(task);
373            assertEquals(0, task.runCount());
374            checkCancelled(task);
375      }      }
376    
377      /**      /**
378       * cancel of a completed task fails       * cancel(false) of a completed task fails
379       */       */
380      public void testCancelAfterRun() {      public void testCancelAfterRun() {
381          FutureTask task = new FutureTask(new NoOpCallable());          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
382          task.run();          task.run();
383          assertFalse(task.cancel(false));          assertFalse(task.cancel(false));
384          assertTrue(task.isDone());          assertEquals(1, task.runCount());
385          assertFalse(task.isCancelled());          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) interrupts a running task       * cancel(true) of a completed task fails
394       */       */
395      public void testCancelInterrupt() throws InterruptedException {      public void testCancelAfterRun2() {
396          final FutureTask task =          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
397              new FutureTask(new CheckedInterruptedCallable<Object>() {          task.run();
398                  public Object realCall() throws InterruptedException {          assertFalse(task.cancel(true));
399                      Thread.sleep(SMALL_DELAY_MS);          assertEquals(1, task.runCount());
400                      return Boolean.TRUE;          assertEquals(1, task.setCount());
401            assertEquals(0, task.setExceptionCount());
402            tryToConfuseDoneTask(task);
403            checkCompletedNormally(task, Boolean.TRUE);
404            assertEquals(1, task.runCount());
405        }
406    
407        /**
408         * cancel(true) interrupts a running task that subsequently succeeds
409         */
410        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                  }});                  }});
421    
422          Thread t = new Thread(task);          Thread t = newStartedThread(task);
423          t.start();          await(pleaseCancel);
         Thread.sleep(SHORT_DELAY_MS);  
424          assertTrue(task.cancel(true));          assertTrue(task.cancel(true));
425          t.join();          assertTrue(task.isCancelled());
426          assertTrue(task.isDone());          assertTrue(task.isDone());
427            awaitTermination(t);
428            assertEquals(1, task.runCount());
429            assertEquals(1, task.setCount());
430            assertEquals(0, task.setExceptionCount());
431            tryToConfuseDoneTask(task);
432            checkCancelled(task);
433        }
434    
435        /**
436         * cancel(true) tries to interrupt a running task, but
437         * Thread.interrupt throws (simulating a restrictive security
438         * manager)
439         */
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            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            await(pleaseCancel);
460            try {
461                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          assertTrue(task.isCancelled());          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         * 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                        pleaseCancel.countDown();
490                        try {
491                            delay(LONG_DELAY_MS);
492                            threadShouldThrow();
493                        } catch (InterruptedException success) {
494                        } catch (Throwable t) { threadUnexpectedException(t); }
495                        throw new RuntimeException();
496                    }});
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            checkCancelled(task);
508        }
509    
510      /**      /**
511       * cancel(false) does not interrupt a running task       * cancel(false) does not interrupt a running task
512       */       */
513      public void testCancelNoInterrupt() throws InterruptedException {      public void testCancelNoInterrupt() {
514          final FutureTask task =          final CountDownLatch pleaseCancel = new CountDownLatch(1);
515              new FutureTask(new CheckedCallable<Object>() {          final CountDownLatch cancelled = new CountDownLatch(1);
516                  public Object realCall() throws InterruptedException {          final PublicFutureTask task =
517                      Thread.sleep(MEDIUM_DELAY_MS);              new PublicFutureTask(new CheckedCallable<Boolean>() {
518                    public Boolean realCall() {
519                        pleaseCancel.countDown();
520                        await(cancelled);
521                        assertFalse(Thread.interrupted());
522                      return Boolean.TRUE;                      return Boolean.TRUE;
523                  }});                  }});
524    
525          Thread t = new Thread(task);          Thread t = newStartedThread(task);
526          t.start();          await(pleaseCancel);
         Thread.sleep(SHORT_DELAY_MS);  
527          assertTrue(task.cancel(false));          assertTrue(task.cancel(false));
         t.join();  
         assertTrue(task.isDone());  
528          assertTrue(task.isCancelled());          assertTrue(task.isCancelled());
529            cancelled.countDown();
530            awaitTermination(t);
531            assertEquals(1, task.runCount());
532            assertEquals(1, task.setCount());
533            assertEquals(0, task.setExceptionCount());
534            tryToConfuseDoneTask(task);
535            checkCancelled(task);
536      }      }
537    
538      /**      /**
539       * set in one thread causes get in another thread to retrieve value       * run in one thread causes get in another thread to retrieve value
540       */       */
541      public void testGet1() throws InterruptedException {      public void testGetRun() {
542          final FutureTask ft =          final CountDownLatch pleaseRun = new CountDownLatch(2);
543              new FutureTask(new CheckedCallable<Object>() {  
544                  public Object realCall() throws InterruptedException {          final PublicFutureTask task =
545                      return Boolean.TRUE;              new PublicFutureTask(new CheckedCallable<Object>() {
546                    public Object realCall() {
547                        return two;
548                  }});                  }});
549          Thread t = new Thread(new CheckedRunnable() {  
550            Thread t1 = newStartedThread(new CheckedRunnable() {
551              public void realRun() throws Exception {              public void realRun() throws Exception {
552                  assertSame(Boolean.TRUE, ft.get());                  pleaseRun.countDown();
553                    assertSame(two, task.get());
554              }});              }});
555    
556          assertFalse(ft.isDone());          Thread t2 = newStartedThread(new CheckedRunnable() {
557          assertFalse(ft.isCancelled());              public void realRun() throws Exception {
558          t.start();                  pleaseRun.countDown();
559          Thread.sleep(SHORT_DELAY_MS);                  assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
560          ft.run();              }});
561          t.join();  
562          assertTrue(ft.isDone());          await(pleaseRun);
563          assertFalse(ft.isCancelled());          checkNotDone(task);
564            assertTrue(t1.isAlive());
565            assertTrue(t2.isAlive());
566            task.run();
567            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      }      }
576    
577      /**      /**
578       * set in one thread causes timed get in another thread to retrieve value       * set in one thread causes get in another thread to retrieve value
579       */       */
580      public void testTimedGet1() throws InterruptedException {      public void testGetSet() {
581          final FutureTask ft =          final CountDownLatch pleaseSet = new CountDownLatch(2);
582              new FutureTask(new CheckedCallable<Object>() {  
583            final PublicFutureTask task =
584                new PublicFutureTask(new CheckedCallable<Object>() {
585                  public Object realCall() throws InterruptedException {                  public Object realCall() throws InterruptedException {
586                      return Boolean.TRUE;                      return two;
587                  }});                  }});
588          Thread t = new Thread(new CheckedRunnable() {  
589            Thread t1 = newStartedThread(new CheckedRunnable() {
590              public void realRun() throws Exception {              public void realRun() throws Exception {
591                  assertSame(Boolean.TRUE, ft.get(SMALL_DELAY_MS, MILLISECONDS));                  pleaseSet.countDown();
592                    assertSame(two, task.get());
593              }});              }});
594    
595          assertFalse(ft.isDone());          Thread t2 = newStartedThread(new CheckedRunnable() {
596          assertFalse(ft.isCancelled());              public void realRun() throws Exception {
597          t.start();                  pleaseSet.countDown();
598          Thread.sleep(SHORT_DELAY_MS);                  assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
599          ft.run();              }});
600          t.join();  
601          assertTrue(ft.isDone());          await(pleaseSet);
602          assertFalse(ft.isCancelled());          checkNotDone(task);
603            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      }      }
614    
615      /**      /**
616       *  Cancelling a task causes timed get in another thread to throw CancellationException       * Cancelling a task causes timed get in another thread to throw
617       */       * CancellationException
618      public void testTimedGet_Cancellation() throws InterruptedException {       */
619          final FutureTask ft =      public void testTimedGet_Cancellation() {
620              new FutureTask(new CheckedInterruptedCallable<Object>() {          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 {                  public Object realCall() throws InterruptedException {
631                      Thread.sleep(SMALL_DELAY_MS);                  pleaseCancel.countDown();
632                      return Boolean.TRUE;                  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    
643          Thread t1 = new ThreadShouldThrow(CancellationException.class) {          Thread t1 = new ThreadShouldThrow(CancellationException.class) {
644              public void realRun() throws Exception {              public void realRun() throws Exception {
645                  ft.get(MEDIUM_DELAY_MS, MILLISECONDS);                      pleaseCancel.countDown();
646                        task.get();
647              }};              }};
648          Thread t2 = new Thread(ft);          Thread t2 = new ThreadShouldThrow(CancellationException.class) {
         t1.start();  
         t2.start();  
         Thread.sleep(SHORT_DELAY_MS);  
         ft.cancel(true);  
         t1.join();  
         t2.join();  
     }  
   
     /**  
      * Cancelling a task causes get in another thread to throw CancellationException  
      */  
     public void testGet_Cancellation() throws InterruptedException {  
         final FutureTask ft =  
             new FutureTask(new CheckedInterruptedCallable<Object>() {  
                 public Object realCall() throws InterruptedException {  
                     Thread.sleep(SMALL_DELAY_MS);  
                     return Boolean.TRUE;  
                 }});  
         Thread t1 = new ThreadShouldThrow(CancellationException.class) {  
649              public void realRun() throws Exception {              public void realRun() throws Exception {
650                  ft.get();                      pleaseCancel.countDown();
651                        task.get(2*LONG_DELAY_MS, MILLISECONDS);
652              }};              }};
   
         Thread t2 = new Thread(ft);  
653          t1.start();          t1.start();
654          t2.start();          t2.start();
655          Thread.sleep(SHORT_DELAY_MS);          Thread t3 = newStartedThread(task);
656          ft.cancel(true);          await(pleaseCancel);
657          t1.join();          checkIsRunning(task);
658          t2.join();          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      }      }
670    
   
671      /**      /**
672       * A runtime exception in task causes get to throw ExecutionException       * A runtime exception in task causes get to throw ExecutionException
673       */       */
674      public void testGet_ExecutionException() throws InterruptedException {      public void testGet_ExecutionException() throws InterruptedException {
675          final FutureTask ft = new FutureTask(new Callable() {          final ArithmeticException e = new ArithmeticException();
676            final PublicFutureTask task = new PublicFutureTask(new Callable() {
677              public Object call() {              public Object call() {
678                  return 5/0;                  throw e;
679              }});              }});
680    
681          ft.run();          task.run();
682            assertEquals(1, task.runCount());
683            assertEquals(0, task.setCount());
684            assertEquals(1, task.setExceptionCount());
685          try {          try {
686              ft.get();              task.get();
687              shouldThrow();              shouldThrow();
688          } catch (ExecutionException success) {          } catch (ExecutionException success) {
689              assertTrue(success.getCause() instanceof ArithmeticException);              assertSame(e, success.getCause());
690                tryToConfuseDoneTask(task);
691                checkCompletedAbnormally(task, success.getCause());
692          }          }
693      }      }
694    
# Line 299  Line 696 
696       *  A runtime exception in task causes timed get to throw ExecutionException       *  A runtime exception in task causes timed get to throw ExecutionException
697       */       */
698      public void testTimedGet_ExecutionException2() throws Exception {      public void testTimedGet_ExecutionException2() throws Exception {
699          final FutureTask ft = new FutureTask(new Callable() {          final ArithmeticException e = new ArithmeticException();
700            final PublicFutureTask task = new PublicFutureTask(new Callable() {
701              public Object call() {              public Object call() {
702                  return 5/0;                  throw e;
703              }});              }});
704    
705          ft.run();          task.run();
706          try {          try {
707              ft.get(SHORT_DELAY_MS, MILLISECONDS);              task.get(LONG_DELAY_MS, MILLISECONDS);
708              shouldThrow();              shouldThrow();
709          } catch (ExecutionException success) {          } catch (ExecutionException success) {
710              assertTrue(success.getCause() instanceof ArithmeticException);              assertSame(e, success.getCause());
711                tryToConfuseDoneTask(task);
712                checkCompletedAbnormally(task, success.getCause());
713          }          }
714      }      }
715    
   
716      /**      /**
717       * Interrupting a waiting get causes it to throw InterruptedException       * get is interruptible
718       */       */
719      public void testGet_InterruptedException() throws InterruptedException {      public void testGet_interruptible() {
720          final FutureTask ft = new FutureTask(new NoOpCallable());          final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
721          Thread t = new Thread(new CheckedInterruptedRunnable() {          final FutureTask task = new FutureTask(new NoOpCallable());
722            Thread t = newStartedThread(new CheckedRunnable() {
723              public void realRun() throws Exception {              public void realRun() throws Exception {
724                  ft.get();                  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              }});              }});
738    
739          t.start();          await(pleaseInterrupt);
         Thread.sleep(SHORT_DELAY_MS);  
740          t.interrupt();          t.interrupt();
741          t.join();          awaitTermination(t);
742            checkNotDone(task);
743      }      }
744    
745      /**      /**
746       *  Interrupting a waiting timed get causes it to throw InterruptedException       * timed get is interruptible
747       */       */
748      public void testTimedGet_InterruptedException2() throws InterruptedException {      public void testTimedGet_interruptible() {
749          final FutureTask ft = new FutureTask(new NoOpCallable());          final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
750          Thread t = new Thread(new CheckedInterruptedRunnable() {          final FutureTask task = new FutureTask(new NoOpCallable());
751            Thread t = newStartedThread(new CheckedRunnable() {
752              public void realRun() throws Exception {              public void realRun() throws Exception {
753                  ft.get(LONG_DELAY_MS,MILLISECONDS);                  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              }});              }});
767    
768          t.start();          await(pleaseInterrupt);
         Thread.sleep(SHORT_DELAY_MS);  
769          t.interrupt();          t.interrupt();
770          t.join();          awaitTermination(t);
771            checkNotDone(task);
772      }      }
773    
774      /**      /**
775       * A timed out timed get throws TimeoutException       * A timed out timed get throws TimeoutException
776       */       */
777      public void testGet_TimeoutException() throws Exception {      public void testGet_TimeoutException() throws Exception {
778            FutureTask task = new FutureTask(new NoOpCallable());
779            long startTime = System.nanoTime();
780            try {
781                task.get(timeoutMillis(), MILLISECONDS);
782                shouldThrow();
783            } 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 {          try {
797              FutureTask ft = new FutureTask(new NoOpCallable());                  task.get(timeout, null);
             ft.get(1,MILLISECONDS);  
798              shouldThrow();              shouldThrow();
799          } catch (TimeoutException success) {}              } 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        }
811    
812        /**
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  }  }

Legend:
Removed from v.1.19  
changed lines
  Added in v.1.42

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8