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

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.39

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8