[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.45, Sun May 14 00:56:43 2017 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 static java.util.concurrent.TimeUnit.MILLISECONDS;
10  import java.util.concurrent.*;  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  public class FutureTaskTest extends TestCase {  import junit.framework.Test;
28    import junit.framework.TestSuite;
29    
30    public class FutureTaskTest extends JSR166TestCase {
31    
32      public static void main(String[] args) {      public static void main(String[] args) {
33          junit.textui.TestRunner.run (suite());          main(suite(), args);
34      }      }
35      public static Test suite() {      public static Test suite() {
36          return new TestSuite(FutureTaskTest.class);          return new TestSuite(FutureTaskTest.class);
37      }      }
38    
39      private static long SHORT_DELAY_MS = 100;      void checkIsDone(Future<?> f) {
40      private static long MEDIUM_DELAY_MS = 1000;          assertTrue(f.isDone());
41      private static long LONG_DELAY_MS = 10000;          assertFalse(f.cancel(false));
42            assertFalse(f.cancel(true));
43      public void testIsDone(){          if (f instanceof PublicFutureTask) {
44          FutureTask task = new FutureTask( new Callable() {              PublicFutureTask pf = (PublicFutureTask) f;
45                  public Object call() { return Boolean.TRUE; } });              assertEquals(1, pf.doneCount());
46          task.run();              assertFalse(pf.runAndReset());
47          assertTrue(task.isDone());              assertEquals(1, pf.doneCount());
48          assertFalse(task.isCancelled());              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      }      }
   
     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());  
75      }      }
76    
77      public void testCancelBeforeRun2() {      void checkNotDone(Future<?> f) {
78          FutureTask task = new FutureTask( new Callable() {          assertFalse(f.isDone());
79                  public Object call() { return Boolean.TRUE; } });          assertFalse(f.isCancelled());
80          assertTrue(task.cancel(true));          if (f instanceof PublicFutureTask) {
81          task.run();              PublicFutureTask pf = (PublicFutureTask) f;
82          assertTrue(task.isDone());              assertEquals(0, pf.doneCount());
83          assertTrue(task.isCancelled());              assertEquals(0, pf.setCount());
84                assertEquals(0, pf.setExceptionCount());
85            }
86      }      }
87    
88      public void testCancelAfterRun() {      void checkIsRunning(Future<?> f) {
89          FutureTask task = new FutureTask( new Callable() {          checkNotDone(f);
90                  public Object call() { return Boolean.TRUE; } });          if (f instanceof FutureTask) {
91          task.run();              FutureTask ft = (FutureTask<?>) f;
92          assertFalse(task.cancel(false));              // Check that run methods do nothing
93          assertTrue(task.isDone());              ft.run();
94          assertFalse(task.isCancelled());              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      public void testCancelInterrupt(){      <T> void checkCompletedNormally(Future<T> f, T expected) {
106          FutureTask task = new FutureTask( new Callable() {          checkIsDone(f);
107                  public Object call() {          assertFalse(f.isCancelled());
108    
109            try {
110                assertSame(expected, f.get());
111            } catch (Throwable fail) { threadUnexpectedException(fail); }
112                      try {                      try {
113                          Thread.sleep(SHORT_DELAY_MS* 2);              assertSame(expected, f.get(5L, SECONDS));
114                          fail("should throw");          } catch (Throwable fail) { threadUnexpectedException(fail); }
115                      }                      }
116                      catch (InterruptedException success) {}  
117                      return Boolean.TRUE;      void checkCancelled(Future<?> f) {
118                  } });          checkIsDone(f);
119          Thread t = new  Thread(task);          assertTrue(f.isCancelled());
         t.start();  
120    
121          try{          try{
122              Thread.sleep(SHORT_DELAY_MS);              f.get();
123              assertTrue(task.cancel(true));              shouldThrow();
124              t.join();          } catch (CancellationException success) {
125              assertTrue(task.isDone());          } catch (Throwable fail) { threadUnexpectedException(fail); }
126              assertTrue(task.isCancelled());  
127          } catch(InterruptedException e){          try {
128              fail("unexpected exception");              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    
     public void testCancelNoInterrupt(){  
         FutureTask task = new FutureTask( new Callable() {  
                 public Object call() {  
146                      try {                      try {
147                          Thread.sleep(SHORT_DELAY_MS* 2);              f.get();
148                      }              shouldThrow();
149                      catch (InterruptedException success) {          } catch (ExecutionException success) {
150                          fail("should not interrupt");              assertSame(t, success.getCause());
151                      }          } catch (Throwable fail) { threadUnexpectedException(fail); }
                     return Boolean.TRUE;  
                 } });  
         Thread t = new  Thread(task);  
         t.start();  
152    
153          try{          try{
154              Thread.sleep(SHORT_DELAY_MS);              f.get(5L, SECONDS);
155              assertTrue(task.cancel(false));              shouldThrow();
156              t.join();          } catch (ExecutionException success) {
157              assertTrue(task.isDone());              assertSame(t, success.getCause());
158              assertTrue(task.isCancelled());          } catch (Throwable fail) { threadUnexpectedException(fail); }
         } catch(InterruptedException e){  
             fail("unexpected exception");  
         }  
159      }      }
160    
161      public void testGet1() {      /**
162          final FutureTask ft = new FutureTask(new Callable(){       * Subclass to expose protected methods
163                  public Object call(){       */
164                      try{      static class PublicFutureTask extends FutureTask {
165                          Thread.sleep(MEDIUM_DELAY_MS);          private final AtomicInteger runCount;
166                      } catch(InterruptedException e){          private final AtomicInteger doneCount = new AtomicInteger(0);
167                          fail("unexpected exception");          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                    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                      return Boolean.TRUE;          @Override public void done() {
204                assertTrue(isDone());
205                doneCount.incrementAndGet();
206                super.done();
207                  }                  }
208          });          @Override public boolean runAndReset() {
209          Thread t = new Thread(new Runnable(){              runAndResetCount.incrementAndGet();
210                  public void run(){              return super.runAndReset();
211                      try{          }
212                          ft.get();          @Override public void set(Object x) {
213                      } catch(Exception e){              setCount.incrementAndGet();
214                          fail("unexpected exception");              super.set(x);
215            }
216            @Override public void setException(Throwable t) {
217                setExceptionCount.incrementAndGet();
218                super.setException(t);
219                      }                      }
220                  }                  }
             });  
         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");  
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      public void testTimedGet1() {      /**
231          final FutureTask ft = new FutureTask(new Callable(){       * creating a future with a null callable throws NullPointerException
232                  public Object call(){       */
233        public void testConstructor() {
234                      try{                      try{
235                          Thread.sleep(MEDIUM_DELAY_MS);              new FutureTask(null);
236                      } catch(InterruptedException e){              shouldThrow();
237                          fail("unexpected exception");          } catch (NullPointerException success) {}
                     }  
                     return Boolean.TRUE;  
238                  }                  }
239              });  
240          Thread t = new Thread(new Runnable(){      /**
241                  public void run(){       * creating a future with null runnable throws NullPointerException
242         */
243        public void testConstructor2() {
244                      try{                      try{
245                          ft.get(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);              new FutureTask(null, Boolean.TRUE);
246                      } catch(TimeoutException success) {              shouldThrow();
247                      } catch(Exception e){          } catch (NullPointerException success) {}
                         fail("unexpected exception");  
248                      }                      }
249    
250        /**
251         * isDone is true when a task completes
252         */
253        public void testIsDone() {
254            PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
255            assertFalse(task.isDone());
256            task.run();
257            assertTrue(task.isDone());
258            checkCompletedNormally(task, Boolean.TRUE);
259            assertEquals(1, task.runCount());
260                  }                  }
             });  
         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");  
261    
262        /**
263         * runAndReset of a non-cancelled task succeeds
264         */
265        public void testRunAndReset() {
266            PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
267            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      }      }
276    
277        /**
278      public void testGet_Cancellation(){       * runAndReset after cancellation fails
279          final FutureTask ft = new FutureTask(new Callable(){       */
280                  public Object call(){      public void testRunAndResetAfterCancel() {
281                      try{          for (boolean mayInterruptIfRunning : new boolean[] { true, false }) {
282                          Thread.sleep(MEDIUM_DELAY_MS);              PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
283                      } catch(InterruptedException e){              assertTrue(task.cancel(mayInterruptIfRunning));
284                          fail("unexpected exception");              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                      return Boolean.TRUE;              tryToConfuseDoneTask(task);
292                checkCancelled(task);
293            }
294        }
295    
296        /**
297         * setting value causes get to return it
298         */
299        public void testSet() throws Exception {
300            PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
301            task.set(one);
302            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
314         */
315        public void testSetException_get() throws Exception {
316            Exception nse = new NoSuchElementException();
317            PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
318            task.setException(nse);
319    
320          try {          try {
321              Thread.sleep(SHORT_DELAY_MS);              task.get();
322              Thread t = new Thread(new Runnable(){              shouldThrow();
323                      public void run(){          } catch (ExecutionException success) {
324                assertSame(nse, success.getCause());
325                checkCompletedAbnormally(task, nse);
326            }
327    
328                          try{                          try{
329                              ft.get();              task.get(LONG_DELAY_MS, MILLISECONDS);
330                              fail("should throw");              shouldThrow();
331                          } catch(CancellationException success){          } catch (ExecutionException success) {
332                assertSame(nse, success.getCause());
333                checkCompletedAbnormally(task, nse);
334                          }                          }
335                          catch(Exception e){  
336                              fail("unexpected exception");          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         * cancel(false) before run succeeds
345         */
346        public void testCancelBeforeRun() {
347            PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
348            assertTrue(task.cancel(false));
349            task.run();
350            assertEquals(0, task.runCount());
351            assertEquals(0, task.setCount());
352            assertEquals(0, task.setExceptionCount());
353            assertTrue(task.isCancelled());
354            assertTrue(task.isDone());
355            tryToConfuseDoneTask(task);
356            assertEquals(0, task.runCount());
357            checkCancelled(task);
358                      }                      }
359                  });  
360              t.start();      /**
361              ft.cancel(true);       * cancel(true) before run succeeds
362              t.join();       */
363          } catch(InterruptedException success){      public void testCancelBeforeRun2() {
364              fail("unexpected exception");          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
365            assertTrue(task.cancel(true));
366            task.run();
367            assertEquals(0, task.runCount());
368            assertEquals(0, task.setCount());
369            assertEquals(0, task.setExceptionCount());
370            assertTrue(task.isCancelled());
371            assertTrue(task.isDone());
372            tryToConfuseDoneTask(task);
373            assertEquals(0, task.runCount());
374            checkCancelled(task);
375          }          }
376    
377        /**
378         * cancel(false) of a completed task fails
379         */
380        public void testCancelAfterRun() {
381            PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
382            task.run();
383            assertFalse(task.cancel(false));
384            assertEquals(1, task.runCount());
385            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      public void testGet_Cancellation2(){      /**
393          final FutureTask ft = new FutureTask(new Callable(){       * cancel(true) of a completed task fails
394                  public Object call(){       */
395                      try{      public void testCancelAfterRun2() {
396                          Thread.sleep(SHORT_DELAY_MS);          PublicFutureTask task = new PublicFutureTask(new NoOpCallable());
397                      } catch(InterruptedException e) {          task.run();
398                          fail("unexpected exception");          assertFalse(task.cancel(true));
399            assertEquals(1, task.runCount());
400            assertEquals(1, task.setCount());
401            assertEquals(0, task.setExceptionCount());
402            tryToConfuseDoneTask(task);
403            checkCompletedNormally(task, Boolean.TRUE);
404            assertEquals(1, task.runCount());
405                      }                      }
406                      return Boolean.TRUE;  
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                        assertFalse(Thread.interrupted());
421                    }});
422    
423            Thread t = newStartedThread(task);
424            await(pleaseCancel);
425            assertTrue(task.cancel(true));
426            assertTrue(task.isCancelled());
427            assertTrue(task.isDone());
428            awaitTermination(t);
429            assertEquals(1, task.runCount());
430            assertEquals(1, task.setCount());
431            assertEquals(0, task.setExceptionCount());
432            tryToConfuseDoneTask(task);
433            checkCancelled(task);
434                  }                  }
435              });  
436        /**
437         * cancel(true) tries to interrupt a running task, but
438         * Thread.interrupt throws (simulating a restrictive security
439         * manager)
440         */
441        public void testCancelInterrupt_ThrowsSecurityException() {
442            final CountDownLatch pleaseCancel = new CountDownLatch(1);
443            final CountDownLatch cancelled = new CountDownLatch(1);
444            final PublicFutureTask task =
445                new PublicFutureTask(new CheckedRunnable() {
446                    public void realRun() {
447                        pleaseCancel.countDown();
448                        await(cancelled);
449                        assertFalse(Thread.interrupted());
450                    }});
451    
452            final Thread t = new Thread(task) {
453                // Simulate a restrictive security manager.
454                @Override public void interrupt() {
455                    throw new SecurityException();
456                }};
457            t.setDaemon(true);
458            t.start();
459    
460            await(pleaseCancel);
461          try{          try{
462              Thread.sleep(100);              task.cancel(true);
463              Thread t = new Thread(new Runnable(){              shouldThrow();
464            } catch (SecurityException expected) {}
465    
466            // We failed to deliver the interrupt, but the world retains
467            // its sanity, as if we had done task.cancel(false)
468            assertTrue(task.isCancelled());
469            assertTrue(task.isDone());
470            assertEquals(1, task.runCount());
471            assertEquals(1, task.doneCount());
472            assertEquals(0, task.setCount());
473            assertEquals(0, task.setExceptionCount());
474            cancelled.countDown();
475            awaitTermination(t);
476            assertEquals(1, task.setCount());
477            assertEquals(0, task.setExceptionCount());
478            tryToConfuseDoneTask(task);
479            checkCancelled(task);
480        }
481    
482        /**
483         * cancel(true) interrupts a running task that subsequently throws
484         */
485        public void testCancelInterrupt_taskFails() {
486            final CountDownLatch pleaseCancel = new CountDownLatch(1);
487            final PublicFutureTask task =
488                new PublicFutureTask(new Runnable() {
489                      public void run(){                      public void run(){
490                        pleaseCancel.countDown();
491                          try{                          try{
492                              ft.get(3 * SHORT_DELAY_MS, TimeUnit.MILLISECONDS);                          delay(LONG_DELAY_MS);
493                              fail("should throw");                          threadShouldThrow();
494                          } catch(CancellationException success) {}                      } catch (InterruptedException success) {
495                          catch(Exception e){                      } catch (Throwable t) { threadUnexpectedException(t); }
496                              fail("unexpected exception");                      throw new RuntimeException();
497                          }                  }});
498    
499            Thread t = newStartedThread(task);
500            await(pleaseCancel);
501            assertTrue(task.cancel(true));
502            assertTrue(task.isCancelled());
503            awaitTermination(t);
504            assertEquals(1, task.runCount());
505            assertEquals(0, task.setCount());
506            assertEquals(1, task.setExceptionCount());
507            tryToConfuseDoneTask(task);
508            checkCancelled(task);
509                      }                      }
510                  });  
511              t.start();      /**
512              Thread.sleep(SHORT_DELAY_MS);       * cancel(false) does not interrupt a running task
513              ft.cancel(true);       */
514              Thread.sleep(SHORT_DELAY_MS);      public void testCancelNoInterrupt() {
515              t.join();          final CountDownLatch pleaseCancel = new CountDownLatch(1);
516          } catch(InterruptedException ie){          final CountDownLatch cancelled = new CountDownLatch(1);
517              fail("unexpected exception");          final PublicFutureTask task =
518                new PublicFutureTask(new CheckedCallable<Boolean>() {
519                    public Boolean realCall() {
520                        pleaseCancel.countDown();
521                        await(cancelled);
522                        assertFalse(Thread.interrupted());
523                        return Boolean.TRUE;
524                    }});
525    
526            Thread t = newStartedThread(task);
527            await(pleaseCancel);
528            assertTrue(task.cancel(false));
529            assertTrue(task.isCancelled());
530            cancelled.countDown();
531            awaitTermination(t);
532            assertEquals(1, task.runCount());
533            assertEquals(1, task.setCount());
534            assertEquals(0, task.setExceptionCount());
535            tryToConfuseDoneTask(task);
536            checkCancelled(task);
537          }          }
538    
539        /**
540         * run in one thread causes get in another thread to retrieve value
541         */
542        public void testGetRun() {
543            final CountDownLatch pleaseRun = new CountDownLatch(2);
544    
545            final PublicFutureTask task =
546                new PublicFutureTask(new CheckedCallable<Object>() {
547                    public Object realCall() {
548                        return two;
549                    }});
550    
551            Thread t1 = newStartedThread(new CheckedRunnable() {
552                public void realRun() throws Exception {
553                    pleaseRun.countDown();
554                    assertSame(two, task.get());
555                }});
556    
557            Thread t2 = newStartedThread(new CheckedRunnable() {
558                public void realRun() throws Exception {
559                    pleaseRun.countDown();
560                    assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
561                }});
562    
563            await(pleaseRun);
564            checkNotDone(task);
565            assertTrue(t1.isAlive());
566            assertTrue(t2.isAlive());
567            task.run();
568            checkCompletedNormally(task, two);
569            assertEquals(1, task.runCount());
570            assertEquals(1, task.setCount());
571            assertEquals(0, task.setExceptionCount());
572            awaitTermination(t1);
573            awaitTermination(t2);
574            tryToConfuseDoneTask(task);
575            checkCompletedNormally(task, two);
576      }      }
577    
578      public void testGet_ExecutionException(){      /**
579          final FutureTask ft = new FutureTask(new Callable(){       * set in one thread causes get in another thread to retrieve value
580                  public Object call(){       */
581                      int i = 5/0;      public void testGetSet() {
582                      return Boolean.TRUE;          final CountDownLatch pleaseSet = new CountDownLatch(2);
583    
584            final PublicFutureTask task =
585                new PublicFutureTask(new CheckedCallable<Object>() {
586                    public Object realCall() throws InterruptedException {
587                        return two;
588                    }});
589    
590            Thread t1 = newStartedThread(new CheckedRunnable() {
591                public void realRun() throws Exception {
592                    pleaseSet.countDown();
593                    assertSame(two, task.get());
594                }});
595    
596            Thread t2 = newStartedThread(new CheckedRunnable() {
597                public void realRun() throws Exception {
598                    pleaseSet.countDown();
599                    assertSame(two, task.get(2*LONG_DELAY_MS, MILLISECONDS));
600                }});
601    
602            await(pleaseSet);
603            checkNotDone(task);
604            assertTrue(t1.isAlive());
605            assertTrue(t2.isAlive());
606            task.set(two);
607            assertEquals(0, task.runCount());
608            assertEquals(1, task.setCount());
609            assertEquals(0, task.setExceptionCount());
610            tryToConfuseDoneTask(task);
611            checkCompletedNormally(task, two);
612            awaitTermination(t1);
613            awaitTermination(t2);
614        }
615    
616        /**
617         * Cancelling a task causes timed get in another thread to throw
618         * CancellationException
619         */
620        public void testTimedGet_Cancellation() {
621            testTimedGet_Cancellation(false);
622                  }                  }
623              });      public void testTimedGet_Cancellation_interrupt() {
624          try{          testTimedGet_Cancellation(true);
             ft.run();  
             ft.get();  
             fail("should throw");  
         } catch(ExecutionException success){  
625          }          }
626          catch(Exception e){      public void testTimedGet_Cancellation(final boolean mayInterruptIfRunning) {
627              fail("unexpected exception");          final CountDownLatch pleaseCancel = new CountDownLatch(3);
628            final CountDownLatch cancelled = new CountDownLatch(1);
629            final Callable<Object> callable =
630                new CheckedCallable<Object>() {
631                public Object realCall() throws InterruptedException {
632                    pleaseCancel.countDown();
633                    if (mayInterruptIfRunning) {
634                        try {
635                            delay(2*LONG_DELAY_MS);
636                        } catch (InterruptedException success) {}
637                    } else {
638                        await(cancelled);
639          }          }
640                    return two;
641                }};
642            final PublicFutureTask task = new PublicFutureTask(callable);
643    
644            Thread t1 = new ThreadShouldThrow(CancellationException.class) {
645                    public void realRun() throws Exception {
646                        pleaseCancel.countDown();
647                        task.get();
648                    }};
649            Thread t2 = new ThreadShouldThrow(CancellationException.class) {
650                    public void realRun() throws Exception {
651                        pleaseCancel.countDown();
652                        task.get(2*LONG_DELAY_MS, MILLISECONDS);
653                    }};
654            t1.start();
655            t2.start();
656            Thread t3 = newStartedThread(task);
657            await(pleaseCancel);
658            checkIsRunning(task);
659            task.cancel(mayInterruptIfRunning);
660            checkCancelled(task);
661            awaitTermination(t1);
662            awaitTermination(t2);
663            cancelled.countDown();
664            awaitTermination(t3);
665            assertEquals(1, task.runCount());
666            assertEquals(1, task.setCount());
667            assertEquals(0, task.setExceptionCount());
668            tryToConfuseDoneTask(task);
669            checkCancelled(task);
670      }      }
671    
672      public void testTimedGet_ExecutionException2(){      /**
673          final FutureTask ft = new FutureTask(new Callable(){       * A runtime exception in task causes get to throw ExecutionException
674         */
675        public void testGet_ExecutionException() throws InterruptedException {
676            final ArithmeticException e = new ArithmeticException();
677            final PublicFutureTask task = new PublicFutureTask(new Callable() {
678                  public Object call(){                  public Object call(){
679                      int i = 5/0;                  throw e;
680                      return Boolean.TRUE;              }});
681                  }  
682              });          task.run();
683            assertEquals(1, task.runCount());
684            assertEquals(0, task.setCount());
685            assertEquals(1, task.setExceptionCount());
686          try{          try{
687              ft.run();              task.get();
688              ft.get(SHORT_DELAY_MS, TimeUnit.MILLISECONDS);              shouldThrow();
             fail("should throw");  
689          } catch(ExecutionException success) {          } catch(ExecutionException success) {
690          } catch(TimeoutException success) { } // unlikely but OK              assertSame(e, success.getCause());
691          catch(Exception e){              tryToConfuseDoneTask(task);
692              fail("unexpected exception");              checkCompletedAbnormally(task, success.getCause());
693          }          }
694      }      }
695    
696        /**
697      public void testGet_InterruptedException(){       * A runtime exception in task causes timed get to throw ExecutionException
698          final FutureTask ft = new FutureTask(new Callable(){       */
699        public void testTimedGet_ExecutionException2() throws Exception {
700            final ArithmeticException e = new ArithmeticException();
701            final PublicFutureTask task = new PublicFutureTask(new Callable() {
702                  public Object call(){                  public Object call(){
703                      return new Object();                  throw e;
704                  }              }});
705              });  
706          Thread t = new Thread(new Runnable(){          task.run();
                 public void run(){  
707                      try{                      try{
708                          ft.get();              task.get(LONG_DELAY_MS, MILLISECONDS);
709                          fail("should throw");              shouldThrow();
710                      } catch(InterruptedException success){          } catch (ExecutionException success) {
711                      } catch(Exception e){              assertSame(e, success.getCause());
712                          fail("unexpected exception");              tryToConfuseDoneTask(task);
713                checkCompletedAbnormally(task, success.getCause());
714                      }                      }
715                  }                  }
716              });  
717        /**
718         * get is interruptible
719         */
720        public void testGet_interruptible() {
721            final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
722            final FutureTask task = new FutureTask(new NoOpCallable());
723            Thread t = newStartedThread(new CheckedRunnable() {
724                public void realRun() throws Exception {
725                    Thread.currentThread().interrupt();
726          try {          try {
727              t.start();                      task.get();
728              Thread.sleep(SHORT_DELAY_MS);                      shouldThrow();
729                    } catch (InterruptedException success) {}
730                    assertFalse(Thread.interrupted());
731    
732                    pleaseInterrupt.countDown();
733                    try {
734                        task.get();
735                        shouldThrow();
736                    } catch (InterruptedException success) {}
737                    assertFalse(Thread.interrupted());
738                }});
739    
740            await(pleaseInterrupt);
741              t.interrupt();              t.interrupt();
742              t.join();          awaitTermination(t);
743          } catch(Exception e){          checkNotDone(task);
             fail("unexpected exception");  
         }  
744      }      }
745    
746      public void testTimedGet_InterruptedException2(){      /**
747          final FutureTask ft = new FutureTask(new Callable(){       * timed get is interruptible
748                  public Object call(){       */
749                      return new Object();      public void testTimedGet_interruptible() {
750                  }          final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
751              });          final FutureTask task = new FutureTask(new NoOpCallable());
752          Thread t = new Thread(new Runnable(){          Thread t = newStartedThread(new CheckedRunnable() {
753                  public void run(){              public void realRun() throws Exception {
754                    Thread.currentThread().interrupt();
755                      try{                      try{
756                          ft.get(100,TimeUnit.SECONDS);                      task.get(2*LONG_DELAY_MS, MILLISECONDS);
757                          fail("should throw");                      shouldThrow();
758                      } catch(InterruptedException success){}                      } catch(InterruptedException success){}
759                      catch(Exception e){                  assertFalse(Thread.interrupted());
760                          fail("unexpected exception");  
761                      }                  pleaseInterrupt.countDown();
                 }  
             });  
762          try {          try {
763              t.start();                      task.get(2*LONG_DELAY_MS, MILLISECONDS);
764              Thread.sleep(SHORT_DELAY_MS);                      shouldThrow();
765                    } catch (InterruptedException success) {}
766                    assertFalse(Thread.interrupted());
767                }});
768    
769            await(pleaseInterrupt);
770              t.interrupt();              t.interrupt();
771              t.join();          awaitTermination(t);
772          } catch(Exception e){          checkNotDone(task);
773              fail("unexpected exception");      }
774    
775        /**
776         * A timed out timed get throws TimeoutException
777         */
778        public void testGet_TimeoutException() throws Exception {
779            FutureTask task = new FutureTask(new NoOpCallable());
780            long startTime = System.nanoTime();
781            try {
782                task.get(timeoutMillis(), MILLISECONDS);
783                shouldThrow();
784            } catch (TimeoutException success) {
785                assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
786          }          }
787      }      }
788    
789      public void testGet_TimeoutException(){      /**
790          FutureTask ft = new FutureTask(new Callable(){       * timed get with null TimeUnit throws NullPointerException
791                  public Object call(){       */
792                      return new Object();      public void testGet_NullTimeUnit() throws Exception {
793            FutureTask task = new FutureTask(new NoOpCallable());
794            long[] timeouts = { Long.MIN_VALUE, 0L, Long.MAX_VALUE };
795    
796            for (long timeout : timeouts) {
797                try {
798                    task.get(timeout, null);
799                    shouldThrow();
800                } catch (NullPointerException success) {}
801                  }                  }
802              });  
803            task.run();
804    
805            for (long timeout : timeouts) {
806          try{          try{
807              ft.get(1,TimeUnit.MILLISECONDS);                  task.get(timeout, null);
808              fail("should throw");                  shouldThrow();
809          } catch(TimeoutException success){}              } catch (NullPointerException success) {}
810          catch(Exception success){          }
             fail("unexpected exception");  
811          }          }
812    
813        /**
814         * timed get with most negative timeout works correctly (i.e. no
815         * underflow bug)
816         */
817        public void testGet_NegativeInfinityTimeout() throws Exception {
818            final ExecutorService pool = Executors.newFixedThreadPool(10);
819            final Runnable nop = new Runnable() { public void run() {}};
820            final FutureTask<Void> task = new FutureTask<>(nop, null);
821            final List<Future<?>> futures = new ArrayList<>();
822            Runnable r = new Runnable() { public void run() {
823                for (long timeout : new long[] { 0L, -1L, Long.MIN_VALUE }) {
824                    try {
825                        task.get(timeout, NANOSECONDS);
826                        shouldThrow();
827                    } catch (TimeoutException success) {
828                    } catch (Throwable fail) {threadUnexpectedException(fail);}}}};
829            for (int i = 0; i < 10; i++)
830                futures.add(pool.submit(r));
831            try {
832                joinPool(pool);
833                for (Future<?> future : futures)
834                    checkCompletedNormally(future, null);
835            } finally {
836                task.run();         // last resort to help terminate
837            }
838      }      }
839    
840  }  }

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

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8