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

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

Doug Lea
ViewVC Help
Powered by ViewVC 1.0.8