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