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 static java.util.concurrent.TimeUnit.MILLISECONDS;
     12 import static java.util.concurrent.TimeUnit.NANOSECONDS;
     13 
     14 import java.util.ArrayList;
     15 import java.util.List;
     16 import java.util.concurrent.ArrayBlockingQueue;
     17 import java.util.concurrent.BlockingQueue;
     18 import java.util.concurrent.Callable;
     19 import java.util.concurrent.CountDownLatch;
     20 import java.util.concurrent.ExecutionException;
     21 import java.util.concurrent.Executors;
     22 import java.util.concurrent.ExecutorService;
     23 import java.util.concurrent.Future;
     24 import java.util.concurrent.FutureTask;
     25 import java.util.concurrent.LinkedBlockingQueue;
     26 import java.util.concurrent.RejectedExecutionException;
     27 import java.util.concurrent.RejectedExecutionHandler;
     28 import java.util.concurrent.SynchronousQueue;
     29 import java.util.concurrent.ThreadFactory;
     30 import java.util.concurrent.ThreadPoolExecutor;
     31 import java.util.concurrent.TimeUnit;
     32 
     33 import junit.framework.Test;
     34 import junit.framework.TestSuite;
     35 
     36 public class ThreadPoolExecutorTest extends JSR166TestCase {
     37     // android-note: Removed because the CTS runner does a bad job of
     38     // retrying tests that have suite() declarations.
     39     //
     40     // public static void main(String[] args) {
     41     //     main(suite(), args);
     42     // }
     43     // public static Test suite() {
     44     //     return new TestSuite(...);
     45     // }
     46 
     47     static class ExtendedTPE extends ThreadPoolExecutor {
     48         final CountDownLatch beforeCalled = new CountDownLatch(1);
     49         final CountDownLatch afterCalled = new CountDownLatch(1);
     50         final CountDownLatch terminatedCalled = new CountDownLatch(1);
     51 
     52         public ExtendedTPE() {
     53             super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
     54         }
     55         protected void beforeExecute(Thread t, Runnable r) {
     56             beforeCalled.countDown();
     57         }
     58         protected void afterExecute(Runnable r, Throwable t) {
     59             afterCalled.countDown();
     60         }
     61         protected void terminated() {
     62             terminatedCalled.countDown();
     63         }
     64 
     65         public boolean beforeCalled() {
     66             return beforeCalled.getCount() == 0;
     67         }
     68         public boolean afterCalled() {
     69             return afterCalled.getCount() == 0;
     70         }
     71         public boolean terminatedCalled() {
     72             return terminatedCalled.getCount() == 0;
     73         }
     74     }
     75 
     76     static class FailingThreadFactory implements ThreadFactory {
     77         int calls = 0;
     78         public Thread newThread(Runnable r) {
     79             if (++calls > 1) return null;
     80             return new Thread(r);
     81         }
     82     }
     83 
     84     /**
     85      * execute successfully executes a runnable
     86      */
     87     public void testExecute() throws InterruptedException {
     88         final ThreadPoolExecutor p =
     89             new ThreadPoolExecutor(1, 1,
     90                                    LONG_DELAY_MS, MILLISECONDS,
     91                                    new ArrayBlockingQueue<Runnable>(10));
     92         final CountDownLatch done = new CountDownLatch(1);
     93         final Runnable task = new CheckedRunnable() {
     94             public void realRun() {
     95                 done.countDown();
     96             }};
     97         try {
     98             p.execute(task);
     99             assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
    100         } finally {
    101             joinPool(p);
    102         }
    103     }
    104 
    105     /**
    106      * getActiveCount increases but doesn't overestimate, when a
    107      * thread becomes active
    108      */
    109     public void testGetActiveCount() throws InterruptedException {
    110         final ThreadPoolExecutor p =
    111             new ThreadPoolExecutor(2, 2,
    112                                    LONG_DELAY_MS, MILLISECONDS,
    113                                    new ArrayBlockingQueue<Runnable>(10));
    114         final CountDownLatch threadStarted = new CountDownLatch(1);
    115         final CountDownLatch done = new CountDownLatch(1);
    116         try {
    117             assertEquals(0, p.getActiveCount());
    118             p.execute(new CheckedRunnable() {
    119                 public void realRun() throws InterruptedException {
    120                     threadStarted.countDown();
    121                     assertEquals(1, p.getActiveCount());
    122                     done.await();
    123                 }});
    124             assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
    125             assertEquals(1, p.getActiveCount());
    126         } finally {
    127             done.countDown();
    128             joinPool(p);
    129         }
    130     }
    131 
    132     /**
    133      * prestartCoreThread starts a thread if under corePoolSize, else doesn't
    134      */
    135     public void testPrestartCoreThread() {
    136         final ThreadPoolExecutor p =
    137             new ThreadPoolExecutor(2, 2,
    138                                    LONG_DELAY_MS, MILLISECONDS,
    139                                    new ArrayBlockingQueue<Runnable>(10));
    140         assertEquals(0, p.getPoolSize());
    141         assertTrue(p.prestartCoreThread());
    142         assertEquals(1, p.getPoolSize());
    143         assertTrue(p.prestartCoreThread());
    144         assertEquals(2, p.getPoolSize());
    145         assertFalse(p.prestartCoreThread());
    146         assertEquals(2, p.getPoolSize());
    147         joinPool(p);
    148     }
    149 
    150     /**
    151      * prestartAllCoreThreads starts all corePoolSize threads
    152      */
    153     public void testPrestartAllCoreThreads() {
    154         final ThreadPoolExecutor p =
    155             new ThreadPoolExecutor(2, 2,
    156                                    LONG_DELAY_MS, MILLISECONDS,
    157                                    new ArrayBlockingQueue<Runnable>(10));
    158         assertEquals(0, p.getPoolSize());
    159         p.prestartAllCoreThreads();
    160         assertEquals(2, p.getPoolSize());
    161         p.prestartAllCoreThreads();
    162         assertEquals(2, p.getPoolSize());
    163         joinPool(p);
    164     }
    165 
    166     /**
    167      * getCompletedTaskCount increases, but doesn't overestimate,
    168      * when tasks complete
    169      */
    170     public void testGetCompletedTaskCount() throws InterruptedException {
    171         final ThreadPoolExecutor p =
    172             new ThreadPoolExecutor(2, 2,
    173                                    LONG_DELAY_MS, MILLISECONDS,
    174                                    new ArrayBlockingQueue<Runnable>(10));
    175         final CountDownLatch threadStarted = new CountDownLatch(1);
    176         final CountDownLatch threadProceed = new CountDownLatch(1);
    177         final CountDownLatch threadDone = new CountDownLatch(1);
    178         try {
    179             assertEquals(0, p.getCompletedTaskCount());
    180             p.execute(new CheckedRunnable() {
    181                 public void realRun() throws InterruptedException {
    182                     threadStarted.countDown();
    183                     assertEquals(0, p.getCompletedTaskCount());
    184                     threadProceed.await();
    185                     threadDone.countDown();
    186                 }});
    187             await(threadStarted);
    188             assertEquals(0, p.getCompletedTaskCount());
    189             threadProceed.countDown();
    190             threadDone.await();
    191             long startTime = System.nanoTime();
    192             while (p.getCompletedTaskCount() != 1) {
    193                 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
    194                     fail("timed out");
    195                 Thread.yield();
    196             }
    197         } finally {
    198             joinPool(p);
    199         }
    200     }
    201 
    202     /**
    203      * getCorePoolSize returns size given in constructor if not otherwise set
    204      */
    205     public void testGetCorePoolSize() {
    206         final ThreadPoolExecutor p =
    207             new ThreadPoolExecutor(1, 1,
    208                                    LONG_DELAY_MS, MILLISECONDS,
    209                                    new ArrayBlockingQueue<Runnable>(10));
    210         assertEquals(1, p.getCorePoolSize());
    211         joinPool(p);
    212     }
    213 
    214     /**
    215      * getKeepAliveTime returns value given in constructor if not otherwise set
    216      */
    217     public void testGetKeepAliveTime() {
    218         final ThreadPoolExecutor p =
    219             new ThreadPoolExecutor(2, 2,
    220                                    1000, MILLISECONDS,
    221                                    new ArrayBlockingQueue<Runnable>(10));
    222         assertEquals(1, p.getKeepAliveTime(TimeUnit.SECONDS));
    223         joinPool(p);
    224     }
    225 
    226     /**
    227      * getThreadFactory returns factory in constructor if not set
    228      */
    229     public void testGetThreadFactory() {
    230         ThreadFactory tf = new SimpleThreadFactory();
    231         final ThreadPoolExecutor p =
    232             new ThreadPoolExecutor(1, 2,
    233                                    LONG_DELAY_MS, MILLISECONDS,
    234                                    new ArrayBlockingQueue<Runnable>(10),
    235                                    tf,
    236                                    new NoOpREHandler());
    237         assertSame(tf, p.getThreadFactory());
    238         joinPool(p);
    239     }
    240 
    241     /**
    242      * setThreadFactory sets the thread factory returned by getThreadFactory
    243      */
    244     public void testSetThreadFactory() {
    245         final ThreadPoolExecutor p =
    246             new ThreadPoolExecutor(1, 2,
    247                                    LONG_DELAY_MS, MILLISECONDS,
    248                                    new ArrayBlockingQueue<Runnable>(10));
    249         ThreadFactory tf = new SimpleThreadFactory();
    250         p.setThreadFactory(tf);
    251         assertSame(tf, p.getThreadFactory());
    252         joinPool(p);
    253     }
    254 
    255     /**
    256      * setThreadFactory(null) throws NPE
    257      */
    258     public void testSetThreadFactoryNull() {
    259         final ThreadPoolExecutor p =
    260             new ThreadPoolExecutor(1, 2,
    261                                    LONG_DELAY_MS, MILLISECONDS,
    262                                    new ArrayBlockingQueue<Runnable>(10));
    263         try {
    264             p.setThreadFactory(null);
    265             shouldThrow();
    266         } catch (NullPointerException success) {
    267         } finally {
    268             joinPool(p);
    269         }
    270     }
    271 
    272     /**
    273      * getRejectedExecutionHandler returns handler in constructor if not set
    274      */
    275     public void testGetRejectedExecutionHandler() {
    276         final RejectedExecutionHandler h = new NoOpREHandler();
    277         final ThreadPoolExecutor p =
    278             new ThreadPoolExecutor(1, 2,
    279                                    LONG_DELAY_MS, MILLISECONDS,
    280                                    new ArrayBlockingQueue<Runnable>(10),
    281                                    h);
    282         assertSame(h, p.getRejectedExecutionHandler());
    283         joinPool(p);
    284     }
    285 
    286     /**
    287      * setRejectedExecutionHandler sets the handler returned by
    288      * getRejectedExecutionHandler
    289      */
    290     public void testSetRejectedExecutionHandler() {
    291         final ThreadPoolExecutor p =
    292             new ThreadPoolExecutor(1, 2,
    293                                    LONG_DELAY_MS, MILLISECONDS,
    294                                    new ArrayBlockingQueue<Runnable>(10));
    295         RejectedExecutionHandler h = new NoOpREHandler();
    296         p.setRejectedExecutionHandler(h);
    297         assertSame(h, p.getRejectedExecutionHandler());
    298         joinPool(p);
    299     }
    300 
    301     /**
    302      * setRejectedExecutionHandler(null) throws NPE
    303      */
    304     public void testSetRejectedExecutionHandlerNull() {
    305         final ThreadPoolExecutor p =
    306             new ThreadPoolExecutor(1, 2,
    307                                    LONG_DELAY_MS, MILLISECONDS,
    308                                    new ArrayBlockingQueue<Runnable>(10));
    309         try {
    310             p.setRejectedExecutionHandler(null);
    311             shouldThrow();
    312         } catch (NullPointerException success) {
    313         } finally {
    314             joinPool(p);
    315         }
    316     }
    317 
    318     /**
    319      * getLargestPoolSize increases, but doesn't overestimate, when
    320      * multiple threads active
    321      */
    322     public void testGetLargestPoolSize() throws InterruptedException {
    323         final int THREADS = 3;
    324         final ThreadPoolExecutor p =
    325             new ThreadPoolExecutor(THREADS, THREADS,
    326                                    LONG_DELAY_MS, MILLISECONDS,
    327                                    new ArrayBlockingQueue<Runnable>(10));
    328         final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
    329         final CountDownLatch done = new CountDownLatch(1);
    330         try {
    331             assertEquals(0, p.getLargestPoolSize());
    332             for (int i = 0; i < THREADS; i++)
    333                 p.execute(new CheckedRunnable() {
    334                     public void realRun() throws InterruptedException {
    335                         threadsStarted.countDown();
    336                         done.await();
    337                         assertEquals(THREADS, p.getLargestPoolSize());
    338                     }});
    339             assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
    340             assertEquals(THREADS, p.getLargestPoolSize());
    341         } finally {
    342             done.countDown();
    343             joinPool(p);
    344             assertEquals(THREADS, p.getLargestPoolSize());
    345         }
    346     }
    347 
    348     /**
    349      * getMaximumPoolSize returns value given in constructor if not
    350      * otherwise set
    351      */
    352     public void testGetMaximumPoolSize() {
    353         final ThreadPoolExecutor p =
    354             new ThreadPoolExecutor(2, 3,
    355                                    LONG_DELAY_MS, MILLISECONDS,
    356                                    new ArrayBlockingQueue<Runnable>(10));
    357         assertEquals(3, p.getMaximumPoolSize());
    358         joinPool(p);
    359     }
    360 
    361     /**
    362      * getPoolSize increases, but doesn't overestimate, when threads
    363      * become active
    364      */
    365     public void testGetPoolSize() throws InterruptedException {
    366         final ThreadPoolExecutor p =
    367             new ThreadPoolExecutor(1, 1,
    368                                    LONG_DELAY_MS, MILLISECONDS,
    369                                    new ArrayBlockingQueue<Runnable>(10));
    370         final CountDownLatch threadStarted = new CountDownLatch(1);
    371         final CountDownLatch done = new CountDownLatch(1);
    372         try {
    373             assertEquals(0, p.getPoolSize());
    374             p.execute(new CheckedRunnable() {
    375                 public void realRun() throws InterruptedException {
    376                     threadStarted.countDown();
    377                     assertEquals(1, p.getPoolSize());
    378                     done.await();
    379                 }});
    380             assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
    381             assertEquals(1, p.getPoolSize());
    382         } finally {
    383             done.countDown();
    384             joinPool(p);
    385         }
    386     }
    387 
    388     /**
    389      * getTaskCount increases, but doesn't overestimate, when tasks submitted
    390      */
    391     public void testGetTaskCount() throws InterruptedException {
    392         final ThreadPoolExecutor p =
    393             new ThreadPoolExecutor(1, 1,
    394                                    LONG_DELAY_MS, MILLISECONDS,
    395                                    new ArrayBlockingQueue<Runnable>(10));
    396         final CountDownLatch threadStarted = new CountDownLatch(1);
    397         final CountDownLatch done = new CountDownLatch(1);
    398         try {
    399             assertEquals(0, p.getTaskCount());
    400             p.execute(new CheckedRunnable() {
    401                 public void realRun() throws InterruptedException {
    402                     threadStarted.countDown();
    403                     assertEquals(1, p.getTaskCount());
    404                     done.await();
    405                 }});
    406             assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
    407             assertEquals(1, p.getTaskCount());
    408         } finally {
    409             done.countDown();
    410             joinPool(p);
    411         }
    412     }
    413 
    414     /**
    415      * isShutdown is false before shutdown, true after
    416      */
    417     public void testIsShutdown() {
    418         final ThreadPoolExecutor p =
    419             new ThreadPoolExecutor(1, 1,
    420                                    LONG_DELAY_MS, MILLISECONDS,
    421                                    new ArrayBlockingQueue<Runnable>(10));
    422         assertFalse(p.isShutdown());
    423         try { p.shutdown(); } catch (SecurityException ok) { return; }
    424         assertTrue(p.isShutdown());
    425         joinPool(p);
    426     }
    427 
    428     /**
    429      * awaitTermination on a non-shutdown pool times out
    430      */
    431     public void testAwaitTermination_timesOut() throws InterruptedException {
    432         final ThreadPoolExecutor p =
    433             new ThreadPoolExecutor(1, 1,
    434                                    LONG_DELAY_MS, MILLISECONDS,
    435                                    new ArrayBlockingQueue<Runnable>(10));
    436         assertFalse(p.isTerminated());
    437         assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS));
    438         assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS));
    439         assertFalse(p.awaitTermination(-1L, NANOSECONDS));
    440         assertFalse(p.awaitTermination(-1L, MILLISECONDS));
    441         assertFalse(p.awaitTermination(0L, NANOSECONDS));
    442         assertFalse(p.awaitTermination(0L, MILLISECONDS));
    443         long timeoutNanos = 999999L;
    444         long startTime = System.nanoTime();
    445         assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS));
    446         assertTrue(System.nanoTime() - startTime >= timeoutNanos);
    447         assertFalse(p.isTerminated());
    448         startTime = System.nanoTime();
    449         long timeoutMillis = timeoutMillis();
    450         assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS));
    451         assertTrue(millisElapsedSince(startTime) >= timeoutMillis);
    452         assertFalse(p.isTerminated());
    453         p.shutdown();
    454         assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    455         assertTrue(p.isTerminated());
    456     }
    457 
    458     /**
    459      * isTerminated is false before termination, true after
    460      */
    461     public void testIsTerminated() throws InterruptedException {
    462         final ThreadPoolExecutor p =
    463             new ThreadPoolExecutor(1, 1,
    464                                    LONG_DELAY_MS, MILLISECONDS,
    465                                    new ArrayBlockingQueue<Runnable>(10));
    466         final CountDownLatch threadStarted = new CountDownLatch(1);
    467         final CountDownLatch done = new CountDownLatch(1);
    468         assertFalse(p.isTerminated());
    469         try {
    470             p.execute(new CheckedRunnable() {
    471                 public void realRun() throws InterruptedException {
    472                     assertFalse(p.isTerminated());
    473                     threadStarted.countDown();
    474                     done.await();
    475                 }});
    476             assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
    477             assertFalse(p.isTerminating());
    478             done.countDown();
    479         } finally {
    480             try { p.shutdown(); } catch (SecurityException ok) { return; }
    481         }
    482         assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    483         assertTrue(p.isTerminated());
    484     }
    485 
    486     /**
    487      * isTerminating is not true when running or when terminated
    488      */
    489     public void testIsTerminating() throws InterruptedException {
    490         final ThreadPoolExecutor p =
    491             new ThreadPoolExecutor(1, 1,
    492                                    LONG_DELAY_MS, MILLISECONDS,
    493                                    new ArrayBlockingQueue<Runnable>(10));
    494         final CountDownLatch threadStarted = new CountDownLatch(1);
    495         final CountDownLatch done = new CountDownLatch(1);
    496         try {
    497             assertFalse(p.isTerminating());
    498             p.execute(new CheckedRunnable() {
    499                 public void realRun() throws InterruptedException {
    500                     assertFalse(p.isTerminating());
    501                     threadStarted.countDown();
    502                     done.await();
    503                 }});
    504             assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
    505             assertFalse(p.isTerminating());
    506             done.countDown();
    507         } finally {
    508             try { p.shutdown(); } catch (SecurityException ok) { return; }
    509         }
    510         assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
    511         assertTrue(p.isTerminated());
    512         assertFalse(p.isTerminating());
    513     }
    514 
    515     /**
    516      * getQueue returns the work queue, which contains queued tasks
    517      */
    518     public void testGetQueue() throws InterruptedException {
    519         final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
    520         final ThreadPoolExecutor p =
    521             new ThreadPoolExecutor(1, 1,
    522                                    LONG_DELAY_MS, MILLISECONDS,
    523                                    q);
    524         final CountDownLatch threadStarted = new CountDownLatch(1);
    525         final CountDownLatch done = new CountDownLatch(1);
    526         try {
    527             FutureTask[] tasks = new FutureTask[5];
    528             for (int i = 0; i < tasks.length; i++) {
    529                 Callable task = new CheckedCallable<Boolean>() {
    530                     public Boolean realCall() throws InterruptedException {
    531                         threadStarted.countDown();
    532                         assertSame(q, p.getQueue());
    533                         done.await();
    534                         return Boolean.TRUE;
    535                     }};
    536                 tasks[i] = new FutureTask(task);
    537                 p.execute(tasks[i]);
    538             }
    539             assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
    540             assertSame(q, p.getQueue());
    541             assertFalse(q.contains(tasks[0]));
    542             assertTrue(q.contains(tasks[tasks.length - 1]));
    543             assertEquals(tasks.length - 1, q.size());
    544         } finally {
    545             done.countDown();
    546             joinPool(p);
    547         }
    548     }
    549 
    550     /**
    551      * remove(task) removes queued task, and fails to remove active task
    552      */
    553     public void testRemove() throws InterruptedException {
    554         BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
    555         final ThreadPoolExecutor p =
    556             new ThreadPoolExecutor(1, 1,
    557                                    LONG_DELAY_MS, MILLISECONDS,
    558                                    q);
    559         Runnable[] tasks = new Runnable[5];
    560         final CountDownLatch threadStarted = new CountDownLatch(1);
    561         final CountDownLatch done = new CountDownLatch(1);
    562         try {
    563             for (int i = 0; i < tasks.length; i++) {
    564                 tasks[i] = new CheckedRunnable() {
    565                     public void realRun() throws InterruptedException {
    566                         threadStarted.countDown();
    567                         done.await();
    568                     }};
    569                 p.execute(tasks[i]);
    570             }
    571             assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
    572             assertFalse(p.remove(tasks[0]));
    573             assertTrue(q.contains(tasks[4]));
    574             assertTrue(q.contains(tasks[3]));
    575             assertTrue(p.remove(tasks[4]));
    576             assertFalse(p.remove(tasks[4]));
    577             assertFalse(q.contains(tasks[4]));
    578             assertTrue(q.contains(tasks[3]));
    579             assertTrue(p.remove(tasks[3]));
    580             assertFalse(q.contains(tasks[3]));
    581         } finally {
    582             done.countDown();
    583             joinPool(p);
    584         }
    585     }
    586 
    587     /**
    588      * purge removes cancelled tasks from the queue
    589      */
    590     public void testPurge() throws InterruptedException {
    591         final CountDownLatch threadStarted = new CountDownLatch(1);
    592         final CountDownLatch done = new CountDownLatch(1);
    593         final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
    594         final ThreadPoolExecutor p =
    595             new ThreadPoolExecutor(1, 1,
    596                                    LONG_DELAY_MS, MILLISECONDS,
    597                                    q);
    598         FutureTask[] tasks = new FutureTask[5];
    599         try {
    600             for (int i = 0; i < tasks.length; i++) {
    601                 Callable task = new CheckedCallable<Boolean>() {
    602                     public Boolean realCall() throws InterruptedException {
    603                         threadStarted.countDown();
    604                         done.await();
    605                         return Boolean.TRUE;
    606                     }};
    607                 tasks[i] = new FutureTask(task);
    608                 p.execute(tasks[i]);
    609             }
    610             assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
    611             assertEquals(tasks.length, p.getTaskCount());
    612             assertEquals(tasks.length - 1, q.size());
    613             assertEquals(1L, p.getActiveCount());
    614             assertEquals(0L, p.getCompletedTaskCount());
    615             tasks[4].cancel(true);
    616             tasks[3].cancel(false);
    617             p.purge();
    618             assertEquals(tasks.length - 3, q.size());
    619             assertEquals(tasks.length - 2, p.getTaskCount());
    620             p.purge();         // Nothing to do
    621             assertEquals(tasks.length - 3, q.size());
    622             assertEquals(tasks.length - 2, p.getTaskCount());
    623         } finally {
    624             done.countDown();
    625             joinPool(p);
    626         }
    627     }
    628 
    629     /**
    630      * shutdownNow returns a list containing tasks that were not run
    631      */
    632     public void testShutdownNow() {
    633         final ThreadPoolExecutor p =
    634             new ThreadPoolExecutor(1, 1,
    635                                    LONG_DELAY_MS, MILLISECONDS,
    636                                    new ArrayBlockingQueue<Runnable>(10));
    637         List l;
    638         try {
    639             for (int i = 0; i < 5; i++)
    640                 p.execute(new MediumPossiblyInterruptedRunnable());
    641         }
    642         finally {
    643             try {
    644                 l = p.shutdownNow();
    645             } catch (SecurityException ok) { return; }
    646         }
    647         assertTrue(p.isShutdown());
    648         assertTrue(l.size() <= 4);
    649     }
    650 
    651     // Exception Tests
    652 
    653     /**
    654      * Constructor throws if corePoolSize argument is less than zero
    655      */
    656     public void testConstructor1() {
    657         try {
    658             new ThreadPoolExecutor(-1, 1,
    659                                    LONG_DELAY_MS, MILLISECONDS,
    660                                    new ArrayBlockingQueue<Runnable>(10));
    661             shouldThrow();
    662         } catch (IllegalArgumentException success) {}
    663     }
    664 
    665     /**
    666      * Constructor throws if maximumPoolSize is less than zero
    667      */
    668     public void testConstructor2() {
    669         try {
    670             new ThreadPoolExecutor(1, -1,
    671                                    LONG_DELAY_MS, MILLISECONDS,
    672                                    new ArrayBlockingQueue<Runnable>(10));
    673             shouldThrow();
    674         } catch (IllegalArgumentException success) {}
    675     }
    676 
    677     /**
    678      * Constructor throws if maximumPoolSize is equal to zero
    679      */
    680     public void testConstructor3() {
    681         try {
    682             new ThreadPoolExecutor(1, 0,
    683                                    LONG_DELAY_MS, MILLISECONDS,
    684                                    new ArrayBlockingQueue<Runnable>(10));
    685             shouldThrow();
    686         } catch (IllegalArgumentException success) {}
    687     }
    688 
    689     /**
    690      * Constructor throws if keepAliveTime is less than zero
    691      */
    692     public void testConstructor4() {
    693         try {
    694             new ThreadPoolExecutor(1, 2,
    695                                    -1L, MILLISECONDS,
    696                                    new ArrayBlockingQueue<Runnable>(10));
    697             shouldThrow();
    698         } catch (IllegalArgumentException success) {}
    699     }
    700 
    701     /**
    702      * Constructor throws if corePoolSize is greater than the maximumPoolSize
    703      */
    704     public void testConstructor5() {
    705         try {
    706             new ThreadPoolExecutor(2, 1,
    707                                    LONG_DELAY_MS, MILLISECONDS,
    708                                    new ArrayBlockingQueue<Runnable>(10));
    709             shouldThrow();
    710         } catch (IllegalArgumentException success) {}
    711     }
    712 
    713     /**
    714      * Constructor throws if workQueue is set to null
    715      */
    716     public void testConstructorNullPointerException() {
    717         try {
    718             new ThreadPoolExecutor(1, 2,
    719                                    LONG_DELAY_MS, MILLISECONDS,
    720                                    (BlockingQueue) null);
    721             shouldThrow();
    722         } catch (NullPointerException success) {}
    723     }
    724 
    725     /**
    726      * Constructor throws if corePoolSize argument is less than zero
    727      */
    728     public void testConstructor6() {
    729         try {
    730             new ThreadPoolExecutor(-1, 1,
    731                                    LONG_DELAY_MS, MILLISECONDS,
    732                                    new ArrayBlockingQueue<Runnable>(10),
    733                                    new SimpleThreadFactory());
    734             shouldThrow();
    735         } catch (IllegalArgumentException success) {}
    736     }
    737 
    738     /**
    739      * Constructor throws if maximumPoolSize is less than zero
    740      */
    741     public void testConstructor7() {
    742         try {
    743             new ThreadPoolExecutor(1, -1,
    744                                    LONG_DELAY_MS, MILLISECONDS,
    745                                    new ArrayBlockingQueue<Runnable>(10),
    746                                    new SimpleThreadFactory());
    747             shouldThrow();
    748         } catch (IllegalArgumentException success) {}
    749     }
    750 
    751     /**
    752      * Constructor throws if maximumPoolSize is equal to zero
    753      */
    754     public void testConstructor8() {
    755         try {
    756             new ThreadPoolExecutor(1, 0,
    757                                    LONG_DELAY_MS, MILLISECONDS,
    758                                    new ArrayBlockingQueue<Runnable>(10),
    759                                    new SimpleThreadFactory());
    760             shouldThrow();
    761         } catch (IllegalArgumentException success) {}
    762     }
    763 
    764     /**
    765      * Constructor throws if keepAliveTime is less than zero
    766      */
    767     public void testConstructor9() {
    768         try {
    769             new ThreadPoolExecutor(1, 2,
    770                                    -1L, MILLISECONDS,
    771                                    new ArrayBlockingQueue<Runnable>(10),
    772                                    new SimpleThreadFactory());
    773             shouldThrow();
    774         } catch (IllegalArgumentException success) {}
    775     }
    776 
    777     /**
    778      * Constructor throws if corePoolSize is greater than the maximumPoolSize
    779      */
    780     public void testConstructor10() {
    781         try {
    782             new ThreadPoolExecutor(2, 1,
    783                                    LONG_DELAY_MS, MILLISECONDS,
    784                                    new ArrayBlockingQueue<Runnable>(10),
    785                                    new SimpleThreadFactory());
    786             shouldThrow();
    787         } catch (IllegalArgumentException success) {}
    788     }
    789 
    790     /**
    791      * Constructor throws if workQueue is set to null
    792      */
    793     public void testConstructorNullPointerException2() {
    794         try {
    795             new ThreadPoolExecutor(1, 2,
    796                                    LONG_DELAY_MS, MILLISECONDS,
    797                                    (BlockingQueue) null,
    798                                    new SimpleThreadFactory());
    799             shouldThrow();
    800         } catch (NullPointerException success) {}
    801     }
    802 
    803     /**
    804      * Constructor throws if threadFactory is set to null
    805      */
    806     public void testConstructorNullPointerException3() {
    807         try {
    808             new ThreadPoolExecutor(1, 2,
    809                                    LONG_DELAY_MS, MILLISECONDS,
    810                                    new ArrayBlockingQueue<Runnable>(10),
    811                                    (ThreadFactory) null);
    812             shouldThrow();
    813         } catch (NullPointerException success) {}
    814     }
    815 
    816     /**
    817      * Constructor throws if corePoolSize argument is less than zero
    818      */
    819     public void testConstructor11() {
    820         try {
    821             new ThreadPoolExecutor(-1, 1,
    822                                    LONG_DELAY_MS, MILLISECONDS,
    823                                    new ArrayBlockingQueue<Runnable>(10),
    824                                    new NoOpREHandler());
    825             shouldThrow();
    826         } catch (IllegalArgumentException success) {}
    827     }
    828 
    829     /**
    830      * Constructor throws if maximumPoolSize is less than zero
    831      */
    832     public void testConstructor12() {
    833         try {
    834             new ThreadPoolExecutor(1, -1,
    835                                    LONG_DELAY_MS, MILLISECONDS,
    836                                    new ArrayBlockingQueue<Runnable>(10),
    837                                    new NoOpREHandler());
    838             shouldThrow();
    839         } catch (IllegalArgumentException success) {}
    840     }
    841 
    842     /**
    843      * Constructor throws if maximumPoolSize is equal to zero
    844      */
    845     public void testConstructor13() {
    846         try {
    847             new ThreadPoolExecutor(1, 0,
    848                                    LONG_DELAY_MS, MILLISECONDS,
    849                                    new ArrayBlockingQueue<Runnable>(10),
    850                                    new NoOpREHandler());
    851             shouldThrow();
    852         } catch (IllegalArgumentException success) {}
    853     }
    854 
    855     /**
    856      * Constructor throws if keepAliveTime is less than zero
    857      */
    858     public void testConstructor14() {
    859         try {
    860             new ThreadPoolExecutor(1, 2,
    861                                    -1L, MILLISECONDS,
    862                                    new ArrayBlockingQueue<Runnable>(10),
    863                                    new NoOpREHandler());
    864             shouldThrow();
    865         } catch (IllegalArgumentException success) {}
    866     }
    867 
    868     /**
    869      * Constructor throws if corePoolSize is greater than the maximumPoolSize
    870      */
    871     public void testConstructor15() {
    872         try {
    873             new ThreadPoolExecutor(2, 1,
    874                                    LONG_DELAY_MS, MILLISECONDS,
    875                                    new ArrayBlockingQueue<Runnable>(10),
    876                                    new NoOpREHandler());
    877             shouldThrow();
    878         } catch (IllegalArgumentException success) {}
    879     }
    880 
    881     /**
    882      * Constructor throws if workQueue is set to null
    883      */
    884     public void testConstructorNullPointerException4() {
    885         try {
    886             new ThreadPoolExecutor(1, 2,
    887                                    LONG_DELAY_MS, MILLISECONDS,
    888                                    (BlockingQueue) null,
    889                                    new NoOpREHandler());
    890             shouldThrow();
    891         } catch (NullPointerException success) {}
    892     }
    893 
    894     /**
    895      * Constructor throws if handler is set to null
    896      */
    897     public void testConstructorNullPointerException5() {
    898         try {
    899             new ThreadPoolExecutor(1, 2,
    900                                    LONG_DELAY_MS, MILLISECONDS,
    901                                    new ArrayBlockingQueue<Runnable>(10),
    902                                    (RejectedExecutionHandler) null);
    903             shouldThrow();
    904         } catch (NullPointerException success) {}
    905     }
    906 
    907     /**
    908      * Constructor throws if corePoolSize argument is less than zero
    909      */
    910     public void testConstructor16() {
    911         try {
    912             new ThreadPoolExecutor(-1, 1,
    913                                    LONG_DELAY_MS, MILLISECONDS,
    914                                    new ArrayBlockingQueue<Runnable>(10),
    915                                    new SimpleThreadFactory(),
    916                                    new NoOpREHandler());
    917             shouldThrow();
    918         } catch (IllegalArgumentException success) {}
    919     }
    920 
    921     /**
    922      * Constructor throws if maximumPoolSize is less than zero
    923      */
    924     public void testConstructor17() {
    925         try {
    926             new ThreadPoolExecutor(1, -1,
    927                                    LONG_DELAY_MS, MILLISECONDS,
    928                                    new ArrayBlockingQueue<Runnable>(10),
    929                                    new SimpleThreadFactory(),
    930                                    new NoOpREHandler());
    931             shouldThrow();
    932         } catch (IllegalArgumentException success) {}
    933     }
    934 
    935     /**
    936      * Constructor throws if maximumPoolSize is equal to zero
    937      */
    938     public void testConstructor18() {
    939         try {
    940             new ThreadPoolExecutor(1, 0,
    941                                    LONG_DELAY_MS, MILLISECONDS,
    942                                    new ArrayBlockingQueue<Runnable>(10),
    943                                    new SimpleThreadFactory(),
    944                                    new NoOpREHandler());
    945             shouldThrow();
    946         } catch (IllegalArgumentException success) {}
    947     }
    948 
    949     /**
    950      * Constructor throws if keepAliveTime is less than zero
    951      */
    952     public void testConstructor19() {
    953         try {
    954             new ThreadPoolExecutor(1, 2,
    955                                    -1L, MILLISECONDS,
    956                                    new ArrayBlockingQueue<Runnable>(10),
    957                                    new SimpleThreadFactory(),
    958                                    new NoOpREHandler());
    959             shouldThrow();
    960         } catch (IllegalArgumentException success) {}
    961     }
    962 
    963     /**
    964      * Constructor throws if corePoolSize is greater than the maximumPoolSize
    965      */
    966     public void testConstructor20() {
    967         try {
    968             new ThreadPoolExecutor(2, 1,
    969                                    LONG_DELAY_MS, MILLISECONDS,
    970                                    new ArrayBlockingQueue<Runnable>(10),
    971                                    new SimpleThreadFactory(),
    972                                    new NoOpREHandler());
    973             shouldThrow();
    974         } catch (IllegalArgumentException success) {}
    975     }
    976 
    977     /**
    978      * Constructor throws if workQueue is null
    979      */
    980     public void testConstructorNullPointerException6() {
    981         try {
    982             new ThreadPoolExecutor(1, 2,
    983                                    LONG_DELAY_MS, MILLISECONDS,
    984                                    (BlockingQueue) null,
    985                                    new SimpleThreadFactory(),
    986                                    new NoOpREHandler());
    987             shouldThrow();
    988         } catch (NullPointerException success) {}
    989     }
    990 
    991     /**
    992      * Constructor throws if handler is null
    993      */
    994     public void testConstructorNullPointerException7() {
    995         try {
    996             new ThreadPoolExecutor(1, 2,
    997                                    LONG_DELAY_MS, MILLISECONDS,
    998                                    new ArrayBlockingQueue<Runnable>(10),
    999                                    new SimpleThreadFactory(),
   1000                                    (RejectedExecutionHandler) null);
   1001             shouldThrow();
   1002         } catch (NullPointerException success) {}
   1003     }
   1004 
   1005     /**
   1006      * Constructor throws if ThreadFactory is null
   1007      */
   1008     public void testConstructorNullPointerException8() {
   1009         try {
   1010             new ThreadPoolExecutor(1, 2,
   1011                                    LONG_DELAY_MS, MILLISECONDS,
   1012                                    new ArrayBlockingQueue<Runnable>(10),
   1013                                    (ThreadFactory) null,
   1014                                    new NoOpREHandler());
   1015             shouldThrow();
   1016         } catch (NullPointerException success) {}
   1017     }
   1018 
   1019     /**
   1020      * get of submitted callable throws InterruptedException if interrupted
   1021      */
   1022     public void testInterruptedSubmit() throws InterruptedException {
   1023         final ThreadPoolExecutor p =
   1024             new ThreadPoolExecutor(1, 1,
   1025                                    60, TimeUnit.SECONDS,
   1026                                    new ArrayBlockingQueue<Runnable>(10));
   1027 
   1028         final CountDownLatch threadStarted = new CountDownLatch(1);
   1029         final CountDownLatch done = new CountDownLatch(1);
   1030         try {
   1031             Thread t = newStartedThread(new CheckedInterruptedRunnable() {
   1032                 public void realRun() throws Exception {
   1033                     Callable task = new CheckedCallable<Boolean>() {
   1034                         public Boolean realCall() throws InterruptedException {
   1035                             threadStarted.countDown();
   1036                             done.await();
   1037                             return Boolean.TRUE;
   1038                         }};
   1039                     p.submit(task).get();
   1040                 }});
   1041 
   1042             assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
   1043             t.interrupt();
   1044             awaitTermination(t, MEDIUM_DELAY_MS);
   1045         } finally {
   1046             done.countDown();
   1047             joinPool(p);
   1048         }
   1049     }
   1050 
   1051     /**
   1052      * execute throws RejectedExecutionException if saturated.
   1053      */
   1054     public void testSaturatedExecute() {
   1055         ThreadPoolExecutor p =
   1056             new ThreadPoolExecutor(1, 1,
   1057                                    LONG_DELAY_MS, MILLISECONDS,
   1058                                    new ArrayBlockingQueue<Runnable>(1));
   1059         final CountDownLatch done = new CountDownLatch(1);
   1060         try {
   1061             Runnable task = new CheckedRunnable() {
   1062                 public void realRun() throws InterruptedException {
   1063                     done.await();
   1064                 }};
   1065             for (int i = 0; i < 2; ++i)
   1066                 p.execute(task);
   1067             for (int i = 0; i < 2; ++i) {
   1068                 try {
   1069                     p.execute(task);
   1070                     shouldThrow();
   1071                 } catch (RejectedExecutionException success) {}
   1072                 assertTrue(p.getTaskCount() <= 2);
   1073             }
   1074         } finally {
   1075             done.countDown();
   1076             joinPool(p);
   1077         }
   1078     }
   1079 
   1080     /**
   1081      * submit(runnable) throws RejectedExecutionException if saturated.
   1082      */
   1083     public void testSaturatedSubmitRunnable() {
   1084         ThreadPoolExecutor p =
   1085             new ThreadPoolExecutor(1, 1,
   1086                                    LONG_DELAY_MS, MILLISECONDS,
   1087                                    new ArrayBlockingQueue<Runnable>(1));
   1088         final CountDownLatch done = new CountDownLatch(1);
   1089         try {
   1090             Runnable task = new CheckedRunnable() {
   1091                 public void realRun() throws InterruptedException {
   1092                     done.await();
   1093                 }};
   1094             for (int i = 0; i < 2; ++i)
   1095                 p.submit(task);
   1096             for (int i = 0; i < 2; ++i) {
   1097                 try {
   1098                     p.execute(task);
   1099                     shouldThrow();
   1100                 } catch (RejectedExecutionException success) {}
   1101                 assertTrue(p.getTaskCount() <= 2);
   1102             }
   1103         } finally {
   1104             done.countDown();
   1105             joinPool(p);
   1106         }
   1107     }
   1108 
   1109     /**
   1110      * submit(callable) throws RejectedExecutionException if saturated.
   1111      */
   1112     public void testSaturatedSubmitCallable() {
   1113         ThreadPoolExecutor p =
   1114             new ThreadPoolExecutor(1, 1,
   1115                                    LONG_DELAY_MS, MILLISECONDS,
   1116                                    new ArrayBlockingQueue<Runnable>(1));
   1117         final CountDownLatch done = new CountDownLatch(1);
   1118         try {
   1119             Runnable task = new CheckedRunnable() {
   1120                 public void realRun() throws InterruptedException {
   1121                     done.await();
   1122                 }};
   1123             for (int i = 0; i < 2; ++i)
   1124                 p.submit(Executors.callable(task));
   1125             for (int i = 0; i < 2; ++i) {
   1126                 try {
   1127                     p.execute(task);
   1128                     shouldThrow();
   1129                 } catch (RejectedExecutionException success) {}
   1130                 assertTrue(p.getTaskCount() <= 2);
   1131             }
   1132         } finally {
   1133             done.countDown();
   1134             joinPool(p);
   1135         }
   1136     }
   1137 
   1138     /**
   1139      * executor using CallerRunsPolicy runs task if saturated.
   1140      */
   1141     public void testSaturatedExecute2() {
   1142         RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy();
   1143         final ThreadPoolExecutor p =
   1144             new ThreadPoolExecutor(1, 1,
   1145                                    LONG_DELAY_MS,
   1146                                    MILLISECONDS,
   1147                                    new ArrayBlockingQueue<Runnable>(1),
   1148                                    h);
   1149         try {
   1150             TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
   1151             for (int i = 0; i < tasks.length; ++i)
   1152                 tasks[i] = new TrackedNoOpRunnable();
   1153             TrackedLongRunnable mr = new TrackedLongRunnable();
   1154             p.execute(mr);
   1155             for (int i = 0; i < tasks.length; ++i)
   1156                 p.execute(tasks[i]);
   1157             for (int i = 1; i < tasks.length; ++i)
   1158                 assertTrue(tasks[i].done);
   1159             try { p.shutdownNow(); } catch (SecurityException ok) { return; }
   1160         } finally {
   1161             joinPool(p);
   1162         }
   1163     }
   1164 
   1165     /**
   1166      * executor using DiscardPolicy drops task if saturated.
   1167      */
   1168     public void testSaturatedExecute3() {
   1169         RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy();
   1170         final ThreadPoolExecutor p =
   1171             new ThreadPoolExecutor(1, 1,
   1172                                    LONG_DELAY_MS, MILLISECONDS,
   1173                                    new ArrayBlockingQueue<Runnable>(1),
   1174                                    h);
   1175         try {
   1176             TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
   1177             for (int i = 0; i < tasks.length; ++i)
   1178                 tasks[i] = new TrackedNoOpRunnable();
   1179             p.execute(new TrackedLongRunnable());
   1180             for (TrackedNoOpRunnable task : tasks)
   1181                 p.execute(task);
   1182             for (TrackedNoOpRunnable task : tasks)
   1183                 assertFalse(task.done);
   1184             try { p.shutdownNow(); } catch (SecurityException ok) { return; }
   1185         } finally {
   1186             joinPool(p);
   1187         }
   1188     }
   1189 
   1190     /**
   1191      * executor using DiscardOldestPolicy drops oldest task if saturated.
   1192      */
   1193     public void testSaturatedExecute4() {
   1194         RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy();
   1195         final ThreadPoolExecutor p =
   1196             new ThreadPoolExecutor(1, 1,
   1197                                    LONG_DELAY_MS, MILLISECONDS,
   1198                                    new ArrayBlockingQueue<Runnable>(1),
   1199                                    h);
   1200         try {
   1201             p.execute(new TrackedLongRunnable());
   1202             TrackedLongRunnable r2 = new TrackedLongRunnable();
   1203             p.execute(r2);
   1204             assertTrue(p.getQueue().contains(r2));
   1205             TrackedNoOpRunnable r3 = new TrackedNoOpRunnable();
   1206             p.execute(r3);
   1207             assertFalse(p.getQueue().contains(r2));
   1208             assertTrue(p.getQueue().contains(r3));
   1209             try { p.shutdownNow(); } catch (SecurityException ok) { return; }
   1210         } finally {
   1211             joinPool(p);
   1212         }
   1213     }
   1214 
   1215     /**
   1216      * execute throws RejectedExecutionException if shutdown
   1217      */
   1218     public void testRejectedExecutionExceptionOnShutdown() {
   1219         ThreadPoolExecutor p =
   1220             new ThreadPoolExecutor(1, 1,
   1221                                    LONG_DELAY_MS, MILLISECONDS,
   1222                                    new ArrayBlockingQueue<Runnable>(1));
   1223         try { p.shutdown(); } catch (SecurityException ok) { return; }
   1224         try {
   1225             p.execute(new NoOpRunnable());
   1226             shouldThrow();
   1227         } catch (RejectedExecutionException success) {}
   1228 
   1229         joinPool(p);
   1230     }
   1231 
   1232     /**
   1233      * execute using CallerRunsPolicy drops task on shutdown
   1234      */
   1235     public void testCallerRunsOnShutdown() {
   1236         RejectedExecutionHandler h = new ThreadPoolExecutor.CallerRunsPolicy();
   1237         final ThreadPoolExecutor p =
   1238             new ThreadPoolExecutor(1, 1,
   1239                                    LONG_DELAY_MS, MILLISECONDS,
   1240                                    new ArrayBlockingQueue<Runnable>(1), h);
   1241 
   1242         try { p.shutdown(); } catch (SecurityException ok) { return; }
   1243         try {
   1244             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
   1245             p.execute(r);
   1246             assertFalse(r.done);
   1247         } finally {
   1248             joinPool(p);
   1249         }
   1250     }
   1251 
   1252     /**
   1253      * execute using DiscardPolicy drops task on shutdown
   1254      */
   1255     public void testDiscardOnShutdown() {
   1256         RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardPolicy();
   1257         ThreadPoolExecutor p =
   1258             new ThreadPoolExecutor(1, 1,
   1259                                    LONG_DELAY_MS, MILLISECONDS,
   1260                                    new ArrayBlockingQueue<Runnable>(1),
   1261                                    h);
   1262 
   1263         try { p.shutdown(); } catch (SecurityException ok) { return; }
   1264         try {
   1265             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
   1266             p.execute(r);
   1267             assertFalse(r.done);
   1268         } finally {
   1269             joinPool(p);
   1270         }
   1271     }
   1272 
   1273     /**
   1274      * execute using DiscardOldestPolicy drops task on shutdown
   1275      */
   1276     public void testDiscardOldestOnShutdown() {
   1277         RejectedExecutionHandler h = new ThreadPoolExecutor.DiscardOldestPolicy();
   1278         ThreadPoolExecutor p =
   1279             new ThreadPoolExecutor(1, 1,
   1280                                    LONG_DELAY_MS, MILLISECONDS,
   1281                                    new ArrayBlockingQueue<Runnable>(1),
   1282                                    h);
   1283 
   1284         try { p.shutdown(); } catch (SecurityException ok) { return; }
   1285         try {
   1286             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
   1287             p.execute(r);
   1288             assertFalse(r.done);
   1289         } finally {
   1290             joinPool(p);
   1291         }
   1292     }
   1293 
   1294     /**
   1295      * execute(null) throws NPE
   1296      */
   1297     public void testExecuteNull() {
   1298         ThreadPoolExecutor p =
   1299             new ThreadPoolExecutor(1, 2,
   1300                                    LONG_DELAY_MS, MILLISECONDS,
   1301                                    new ArrayBlockingQueue<Runnable>(10));
   1302         try {
   1303             p.execute(null);
   1304             shouldThrow();
   1305         } catch (NullPointerException success) {}
   1306 
   1307         joinPool(p);
   1308     }
   1309 
   1310     /**
   1311      * setCorePoolSize of negative value throws IllegalArgumentException
   1312      */
   1313     public void testCorePoolSizeIllegalArgumentException() {
   1314         ThreadPoolExecutor p =
   1315             new ThreadPoolExecutor(1, 2,
   1316                                    LONG_DELAY_MS, MILLISECONDS,
   1317                                    new ArrayBlockingQueue<Runnable>(10));
   1318         try {
   1319             p.setCorePoolSize(-1);
   1320             shouldThrow();
   1321         } catch (IllegalArgumentException success) {
   1322         } finally {
   1323             try { p.shutdown(); } catch (SecurityException ok) { return; }
   1324         }
   1325         joinPool(p);
   1326     }
   1327 
   1328     /**
   1329      * setMaximumPoolSize(int) throws IllegalArgumentException if
   1330      * given a value less the core pool size
   1331      */
   1332     public void testMaximumPoolSizeIllegalArgumentException() {
   1333         ThreadPoolExecutor p =
   1334             new ThreadPoolExecutor(2, 3,
   1335                                    LONG_DELAY_MS, MILLISECONDS,
   1336                                    new ArrayBlockingQueue<Runnable>(10));
   1337         try {
   1338             p.setMaximumPoolSize(1);
   1339             shouldThrow();
   1340         } catch (IllegalArgumentException success) {
   1341         } finally {
   1342             try { p.shutdown(); } catch (SecurityException ok) { return; }
   1343         }
   1344         joinPool(p);
   1345     }
   1346 
   1347     /**
   1348      * setMaximumPoolSize throws IllegalArgumentException
   1349      * if given a negative value
   1350      */
   1351     public void testMaximumPoolSizeIllegalArgumentException2() {
   1352         ThreadPoolExecutor p =
   1353             new ThreadPoolExecutor(2, 3,
   1354                                    LONG_DELAY_MS, MILLISECONDS,
   1355                                    new ArrayBlockingQueue<Runnable>(10));
   1356         try {
   1357             p.setMaximumPoolSize(-1);
   1358             shouldThrow();
   1359         } catch (IllegalArgumentException success) {
   1360         } finally {
   1361             try { p.shutdown(); } catch (SecurityException ok) { return; }
   1362         }
   1363         joinPool(p);
   1364     }
   1365 
   1366     /**
   1367      * setKeepAliveTime throws IllegalArgumentException
   1368      * when given a negative value
   1369      */
   1370     public void testKeepAliveTimeIllegalArgumentException() {
   1371         ThreadPoolExecutor p =
   1372             new ThreadPoolExecutor(2, 3,
   1373                                    LONG_DELAY_MS, MILLISECONDS,
   1374                                    new ArrayBlockingQueue<Runnable>(10));
   1375         try {
   1376             p.setKeepAliveTime(-1,MILLISECONDS);
   1377             shouldThrow();
   1378         } catch (IllegalArgumentException success) {
   1379         } finally {
   1380             try { p.shutdown(); } catch (SecurityException ok) { return; }
   1381         }
   1382         joinPool(p);
   1383     }
   1384 
   1385     /**
   1386      * terminated() is called on termination
   1387      */
   1388     public void testTerminated() {
   1389         ExtendedTPE p = new ExtendedTPE();
   1390         try { p.shutdown(); } catch (SecurityException ok) { return; }
   1391         assertTrue(p.terminatedCalled());
   1392         joinPool(p);
   1393     }
   1394 
   1395     /**
   1396      * beforeExecute and afterExecute are called when executing task
   1397      */
   1398     public void testBeforeAfter() throws InterruptedException {
   1399         ExtendedTPE p = new ExtendedTPE();
   1400         try {
   1401             final CountDownLatch done = new CountDownLatch(1);
   1402             p.execute(new CheckedRunnable() {
   1403                 public void realRun() {
   1404                     done.countDown();
   1405                 }});
   1406             await(p.afterCalled);
   1407             assertEquals(0, done.getCount());
   1408             assertTrue(p.afterCalled());
   1409             assertTrue(p.beforeCalled());
   1410             try { p.shutdown(); } catch (SecurityException ok) { return; }
   1411         } finally {
   1412             joinPool(p);
   1413         }
   1414     }
   1415 
   1416     /**
   1417      * completed submit of callable returns result
   1418      */
   1419     public void testSubmitCallable() throws Exception {
   1420         ExecutorService e =
   1421             new ThreadPoolExecutor(2, 2,
   1422                                    LONG_DELAY_MS, MILLISECONDS,
   1423                                    new ArrayBlockingQueue<Runnable>(10));
   1424         try {
   1425             Future<String> future = e.submit(new StringTask());
   1426             String result = future.get();
   1427             assertSame(TEST_STRING, result);
   1428         } finally {
   1429             joinPool(e);
   1430         }
   1431     }
   1432 
   1433     /**
   1434      * completed submit of runnable returns successfully
   1435      */
   1436     public void testSubmitRunnable() throws Exception {
   1437         ExecutorService e =
   1438             new ThreadPoolExecutor(2, 2,
   1439                                    LONG_DELAY_MS, MILLISECONDS,
   1440                                    new ArrayBlockingQueue<Runnable>(10));
   1441         try {
   1442             Future<?> future = e.submit(new NoOpRunnable());
   1443             future.get();
   1444             assertTrue(future.isDone());
   1445         } finally {
   1446             joinPool(e);
   1447         }
   1448     }
   1449 
   1450     /**
   1451      * completed submit of (runnable, result) returns result
   1452      */
   1453     public void testSubmitRunnable2() throws Exception {
   1454         ExecutorService e =
   1455             new ThreadPoolExecutor(2, 2,
   1456                                    LONG_DELAY_MS, MILLISECONDS,
   1457                                    new ArrayBlockingQueue<Runnable>(10));
   1458         try {
   1459             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
   1460             String result = future.get();
   1461             assertSame(TEST_STRING, result);
   1462         } finally {
   1463             joinPool(e);
   1464         }
   1465     }
   1466 
   1467     /**
   1468      * invokeAny(null) throws NPE
   1469      */
   1470     public void testInvokeAny1() throws Exception {
   1471         ExecutorService e =
   1472             new ThreadPoolExecutor(2, 2,
   1473                                    LONG_DELAY_MS, MILLISECONDS,
   1474                                    new ArrayBlockingQueue<Runnable>(10));
   1475         try {
   1476             e.invokeAny(null);
   1477             shouldThrow();
   1478         } catch (NullPointerException success) {
   1479         } finally {
   1480             joinPool(e);
   1481         }
   1482     }
   1483 
   1484     /**
   1485      * invokeAny(empty collection) throws IAE
   1486      */
   1487     public void testInvokeAny2() throws Exception {
   1488         ExecutorService e =
   1489             new ThreadPoolExecutor(2, 2,
   1490                                    LONG_DELAY_MS, MILLISECONDS,
   1491                                    new ArrayBlockingQueue<Runnable>(10));
   1492         try {
   1493             e.invokeAny(new ArrayList<Callable<String>>());
   1494             shouldThrow();
   1495         } catch (IllegalArgumentException success) {
   1496         } finally {
   1497             joinPool(e);
   1498         }
   1499     }
   1500 
   1501     /**
   1502      * invokeAny(c) throws NPE if c has null elements
   1503      */
   1504     public void testInvokeAny3() throws Exception {
   1505         final CountDownLatch latch = new CountDownLatch(1);
   1506         final ExecutorService e =
   1507             new ThreadPoolExecutor(2, 2,
   1508                                    LONG_DELAY_MS, MILLISECONDS,
   1509                                    new ArrayBlockingQueue<Runnable>(10));
   1510         List<Callable<String>> l = new ArrayList<Callable<String>>();
   1511         l.add(latchAwaitingStringTask(latch));
   1512         l.add(null);
   1513         try {
   1514             e.invokeAny(l);
   1515             shouldThrow();
   1516         } catch (NullPointerException success) {
   1517         } finally {
   1518             latch.countDown();
   1519             joinPool(e);
   1520         }
   1521     }
   1522 
   1523     /**
   1524      * invokeAny(c) throws ExecutionException if no task completes
   1525      */
   1526     public void testInvokeAny4() throws Exception {
   1527         ExecutorService e =
   1528             new ThreadPoolExecutor(2, 2,
   1529                                    LONG_DELAY_MS, MILLISECONDS,
   1530                                    new ArrayBlockingQueue<Runnable>(10));
   1531         List<Callable<String>> l = new ArrayList<Callable<String>>();
   1532         l.add(new NPETask());
   1533         try {
   1534             e.invokeAny(l);
   1535             shouldThrow();
   1536         } catch (ExecutionException success) {
   1537             assertTrue(success.getCause() instanceof NullPointerException);
   1538         } finally {
   1539             joinPool(e);
   1540         }
   1541     }
   1542 
   1543     /**
   1544      * invokeAny(c) returns result of some task
   1545      */
   1546     public void testInvokeAny5() throws Exception {
   1547         ExecutorService e =
   1548             new ThreadPoolExecutor(2, 2,
   1549                                    LONG_DELAY_MS, MILLISECONDS,
   1550                                    new ArrayBlockingQueue<Runnable>(10));
   1551         try {
   1552             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1553             l.add(new StringTask());
   1554             l.add(new StringTask());
   1555             String result = e.invokeAny(l);
   1556             assertSame(TEST_STRING, result);
   1557         } finally {
   1558             joinPool(e);
   1559         }
   1560     }
   1561 
   1562     /**
   1563      * invokeAll(null) throws NPE
   1564      */
   1565     public void testInvokeAll1() throws Exception {
   1566         ExecutorService e =
   1567             new ThreadPoolExecutor(2, 2,
   1568                                    LONG_DELAY_MS, MILLISECONDS,
   1569                                    new ArrayBlockingQueue<Runnable>(10));
   1570         try {
   1571             e.invokeAll(null);
   1572             shouldThrow();
   1573         } catch (NullPointerException success) {
   1574         } finally {
   1575             joinPool(e);
   1576         }
   1577     }
   1578 
   1579     /**
   1580      * invokeAll(empty collection) returns empty collection
   1581      */
   1582     public void testInvokeAll2() throws InterruptedException {
   1583         ExecutorService e =
   1584             new ThreadPoolExecutor(2, 2,
   1585                                    LONG_DELAY_MS, MILLISECONDS,
   1586                                    new ArrayBlockingQueue<Runnable>(10));
   1587         try {
   1588             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
   1589             assertTrue(r.isEmpty());
   1590         } finally {
   1591             joinPool(e);
   1592         }
   1593     }
   1594 
   1595     /**
   1596      * invokeAll(c) throws NPE if c has null elements
   1597      */
   1598     public void testInvokeAll3() throws Exception {
   1599         ExecutorService e =
   1600             new ThreadPoolExecutor(2, 2,
   1601                                    LONG_DELAY_MS, MILLISECONDS,
   1602                                    new ArrayBlockingQueue<Runnable>(10));
   1603         List<Callable<String>> l = new ArrayList<Callable<String>>();
   1604         l.add(new StringTask());
   1605         l.add(null);
   1606         try {
   1607             e.invokeAll(l);
   1608             shouldThrow();
   1609         } catch (NullPointerException success) {
   1610         } finally {
   1611             joinPool(e);
   1612         }
   1613     }
   1614 
   1615     /**
   1616      * get of element of invokeAll(c) throws exception on failed task
   1617      */
   1618     public void testInvokeAll4() throws Exception {
   1619         ExecutorService e =
   1620             new ThreadPoolExecutor(2, 2,
   1621                                    LONG_DELAY_MS, MILLISECONDS,
   1622                                    new ArrayBlockingQueue<Runnable>(10));
   1623         try {
   1624             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1625             l.add(new NPETask());
   1626             List<Future<String>> futures = e.invokeAll(l);
   1627             assertEquals(1, futures.size());
   1628             try {
   1629                 futures.get(0).get();
   1630                 shouldThrow();
   1631             } catch (ExecutionException success) {
   1632                 assertTrue(success.getCause() instanceof NullPointerException);
   1633             }
   1634         } finally {
   1635             joinPool(e);
   1636         }
   1637     }
   1638 
   1639     /**
   1640      * invokeAll(c) returns results of all completed tasks
   1641      */
   1642     public void testInvokeAll5() throws Exception {
   1643         ExecutorService e =
   1644             new ThreadPoolExecutor(2, 2,
   1645                                    LONG_DELAY_MS, MILLISECONDS,
   1646                                    new ArrayBlockingQueue<Runnable>(10));
   1647         try {
   1648             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1649             l.add(new StringTask());
   1650             l.add(new StringTask());
   1651             List<Future<String>> futures = e.invokeAll(l);
   1652             assertEquals(2, futures.size());
   1653             for (Future<String> future : futures)
   1654                 assertSame(TEST_STRING, future.get());
   1655         } finally {
   1656             joinPool(e);
   1657         }
   1658     }
   1659 
   1660     /**
   1661      * timed invokeAny(null) throws NPE
   1662      */
   1663     public void testTimedInvokeAny1() throws Exception {
   1664         ExecutorService e =
   1665             new ThreadPoolExecutor(2, 2,
   1666                                    LONG_DELAY_MS, MILLISECONDS,
   1667                                    new ArrayBlockingQueue<Runnable>(10));
   1668         try {
   1669             e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
   1670             shouldThrow();
   1671         } catch (NullPointerException success) {
   1672         } finally {
   1673             joinPool(e);
   1674         }
   1675     }
   1676 
   1677     /**
   1678      * timed invokeAny(,,null) throws NPE
   1679      */
   1680     public void testTimedInvokeAnyNullTimeUnit() throws Exception {
   1681         ExecutorService e =
   1682             new ThreadPoolExecutor(2, 2,
   1683                                    LONG_DELAY_MS, MILLISECONDS,
   1684                                    new ArrayBlockingQueue<Runnable>(10));
   1685         List<Callable<String>> l = new ArrayList<Callable<String>>();
   1686         l.add(new StringTask());
   1687         try {
   1688             e.invokeAny(l, MEDIUM_DELAY_MS, null);
   1689             shouldThrow();
   1690         } catch (NullPointerException success) {
   1691         } finally {
   1692             joinPool(e);
   1693         }
   1694     }
   1695 
   1696     /**
   1697      * timed invokeAny(empty collection) throws IAE
   1698      */
   1699     public void testTimedInvokeAny2() throws Exception {
   1700         ExecutorService e =
   1701             new ThreadPoolExecutor(2, 2,
   1702                                    LONG_DELAY_MS, MILLISECONDS,
   1703                                    new ArrayBlockingQueue<Runnable>(10));
   1704         try {
   1705             e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
   1706             shouldThrow();
   1707         } catch (IllegalArgumentException success) {
   1708         } finally {
   1709             joinPool(e);
   1710         }
   1711     }
   1712 
   1713     /**
   1714      * timed invokeAny(c) throws NPE if c has null elements
   1715      */
   1716     public void testTimedInvokeAny3() throws Exception {
   1717         final CountDownLatch latch = new CountDownLatch(1);
   1718         final ExecutorService e =
   1719             new ThreadPoolExecutor(2, 2,
   1720                                    LONG_DELAY_MS, MILLISECONDS,
   1721                                    new ArrayBlockingQueue<Runnable>(10));
   1722         List<Callable<String>> l = new ArrayList<Callable<String>>();
   1723         l.add(latchAwaitingStringTask(latch));
   1724         l.add(null);
   1725         try {
   1726             e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
   1727             shouldThrow();
   1728         } catch (NullPointerException success) {
   1729         } finally {
   1730             latch.countDown();
   1731             joinPool(e);
   1732         }
   1733     }
   1734 
   1735     /**
   1736      * timed invokeAny(c) throws ExecutionException if no task completes
   1737      */
   1738     public void testTimedInvokeAny4() throws Exception {
   1739         ExecutorService e =
   1740             new ThreadPoolExecutor(2, 2,
   1741                                    LONG_DELAY_MS, MILLISECONDS,
   1742                                    new ArrayBlockingQueue<Runnable>(10));
   1743         List<Callable<String>> l = new ArrayList<Callable<String>>();
   1744         l.add(new NPETask());
   1745         try {
   1746             e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
   1747             shouldThrow();
   1748         } catch (ExecutionException success) {
   1749             assertTrue(success.getCause() instanceof NullPointerException);
   1750         } finally {
   1751             joinPool(e);
   1752         }
   1753     }
   1754 
   1755     /**
   1756      * timed invokeAny(c) returns result of some task
   1757      */
   1758     public void testTimedInvokeAny5() throws Exception {
   1759         ExecutorService e =
   1760             new ThreadPoolExecutor(2, 2,
   1761                                    LONG_DELAY_MS, MILLISECONDS,
   1762                                    new ArrayBlockingQueue<Runnable>(10));
   1763         try {
   1764             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1765             l.add(new StringTask());
   1766             l.add(new StringTask());
   1767             String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
   1768             assertSame(TEST_STRING, result);
   1769         } finally {
   1770             joinPool(e);
   1771         }
   1772     }
   1773 
   1774     /**
   1775      * timed invokeAll(null) throws NPE
   1776      */
   1777     public void testTimedInvokeAll1() throws Exception {
   1778         ExecutorService e =
   1779             new ThreadPoolExecutor(2, 2,
   1780                                    LONG_DELAY_MS, MILLISECONDS,
   1781                                    new ArrayBlockingQueue<Runnable>(10));
   1782         try {
   1783             e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
   1784             shouldThrow();
   1785         } catch (NullPointerException success) {
   1786         } finally {
   1787             joinPool(e);
   1788         }
   1789     }
   1790 
   1791     /**
   1792      * timed invokeAll(,,null) throws NPE
   1793      */
   1794     public void testTimedInvokeAllNullTimeUnit() throws Exception {
   1795         ExecutorService e =
   1796             new ThreadPoolExecutor(2, 2,
   1797                                    LONG_DELAY_MS, MILLISECONDS,
   1798                                    new ArrayBlockingQueue<Runnable>(10));
   1799         List<Callable<String>> l = new ArrayList<Callable<String>>();
   1800         l.add(new StringTask());
   1801         try {
   1802             e.invokeAll(l, MEDIUM_DELAY_MS, null);
   1803             shouldThrow();
   1804         } catch (NullPointerException success) {
   1805         } finally {
   1806             joinPool(e);
   1807         }
   1808     }
   1809 
   1810     /**
   1811      * timed invokeAll(empty collection) returns empty collection
   1812      */
   1813     public void testTimedInvokeAll2() throws InterruptedException {
   1814         ExecutorService e =
   1815             new ThreadPoolExecutor(2, 2,
   1816                                    LONG_DELAY_MS, MILLISECONDS,
   1817                                    new ArrayBlockingQueue<Runnable>(10));
   1818         try {
   1819             List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
   1820             assertTrue(r.isEmpty());
   1821         } finally {
   1822             joinPool(e);
   1823         }
   1824     }
   1825 
   1826     /**
   1827      * timed invokeAll(c) throws NPE if c has null elements
   1828      */
   1829     public void testTimedInvokeAll3() throws Exception {
   1830         ExecutorService e =
   1831             new ThreadPoolExecutor(2, 2,
   1832                                    LONG_DELAY_MS, MILLISECONDS,
   1833                                    new ArrayBlockingQueue<Runnable>(10));
   1834         List<Callable<String>> l = new ArrayList<Callable<String>>();
   1835         l.add(new StringTask());
   1836         l.add(null);
   1837         try {
   1838             e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
   1839             shouldThrow();
   1840         } catch (NullPointerException success) {
   1841         } finally {
   1842             joinPool(e);
   1843         }
   1844     }
   1845 
   1846     /**
   1847      * get of element of invokeAll(c) throws exception on failed task
   1848      */
   1849     public void testTimedInvokeAll4() throws Exception {
   1850         ExecutorService e =
   1851             new ThreadPoolExecutor(2, 2,
   1852                                    LONG_DELAY_MS, MILLISECONDS,
   1853                                    new ArrayBlockingQueue<Runnable>(10));
   1854         List<Callable<String>> l = new ArrayList<Callable<String>>();
   1855         l.add(new NPETask());
   1856         List<Future<String>> futures =
   1857             e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
   1858         assertEquals(1, futures.size());
   1859         try {
   1860             futures.get(0).get();
   1861             shouldThrow();
   1862         } catch (ExecutionException success) {
   1863             assertTrue(success.getCause() instanceof NullPointerException);
   1864         } finally {
   1865             joinPool(e);
   1866         }
   1867     }
   1868 
   1869     /**
   1870      * timed invokeAll(c) returns results of all completed tasks
   1871      */
   1872     public void testTimedInvokeAll5() throws Exception {
   1873         ExecutorService e =
   1874             new ThreadPoolExecutor(2, 2,
   1875                                    LONG_DELAY_MS, MILLISECONDS,
   1876                                    new ArrayBlockingQueue<Runnable>(10));
   1877         try {
   1878             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1879             l.add(new StringTask());
   1880             l.add(new StringTask());
   1881             List<Future<String>> futures =
   1882                 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
   1883             assertEquals(2, futures.size());
   1884             for (Future<String> future : futures)
   1885                 assertSame(TEST_STRING, future.get());
   1886         } finally {
   1887             joinPool(e);
   1888         }
   1889     }
   1890 
   1891     /**
   1892      * timed invokeAll(c) cancels tasks not completed by timeout
   1893      */
   1894     public void testTimedInvokeAll6() throws Exception {
   1895         ExecutorService e =
   1896             new ThreadPoolExecutor(2, 2,
   1897                                    LONG_DELAY_MS, MILLISECONDS,
   1898                                    new ArrayBlockingQueue<Runnable>(10));
   1899         try {
   1900             List<Callable<String>> l = new ArrayList<Callable<String>>();
   1901             l.add(new StringTask());
   1902             l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
   1903             l.add(new StringTask());
   1904             List<Future<String>> futures =
   1905                 e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
   1906             assertEquals(l.size(), futures.size());
   1907             for (Future future : futures)
   1908                 assertTrue(future.isDone());
   1909             assertFalse(futures.get(0).isCancelled());
   1910             assertTrue(futures.get(1).isCancelled());
   1911         } finally {
   1912             joinPool(e);
   1913         }
   1914     }
   1915 
   1916     /**
   1917      * Execution continues if there is at least one thread even if
   1918      * thread factory fails to create more
   1919      */
   1920     public void testFailingThreadFactory() throws InterruptedException {
   1921         final ExecutorService e =
   1922             new ThreadPoolExecutor(100, 100,
   1923                                    LONG_DELAY_MS, MILLISECONDS,
   1924                                    new LinkedBlockingQueue<Runnable>(),
   1925                                    new FailingThreadFactory());
   1926         try {
   1927             final int TASKS = 100;
   1928             final CountDownLatch done = new CountDownLatch(TASKS);
   1929             for (int k = 0; k < TASKS; ++k)
   1930                 e.execute(new CheckedRunnable() {
   1931                     public void realRun() {
   1932                         done.countDown();
   1933                     }});
   1934             assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
   1935         } finally {
   1936             joinPool(e);
   1937         }
   1938     }
   1939 
   1940     /**
   1941      * allowsCoreThreadTimeOut is by default false.
   1942      */
   1943     public void testAllowsCoreThreadTimeOut() {
   1944         final ThreadPoolExecutor p =
   1945             new ThreadPoolExecutor(2, 2,
   1946                                    1000, MILLISECONDS,
   1947                                    new ArrayBlockingQueue<Runnable>(10));
   1948         assertFalse(p.allowsCoreThreadTimeOut());
   1949         joinPool(p);
   1950     }
   1951 
   1952     /**
   1953      * allowCoreThreadTimeOut(true) causes idle threads to time out
   1954      */
   1955     public void testAllowCoreThreadTimeOut_true() throws Exception {
   1956         long coreThreadTimeOut = SHORT_DELAY_MS;
   1957         final ThreadPoolExecutor p =
   1958             new ThreadPoolExecutor(2, 10,
   1959                                    coreThreadTimeOut, MILLISECONDS,
   1960                                    new ArrayBlockingQueue<Runnable>(10));
   1961         final CountDownLatch threadStarted = new CountDownLatch(1);
   1962         try {
   1963             p.allowCoreThreadTimeOut(true);
   1964             p.execute(new CheckedRunnable() {
   1965                 public void realRun() {
   1966                     threadStarted.countDown();
   1967                     assertEquals(1, p.getPoolSize());
   1968                 }});
   1969             await(threadStarted);
   1970             delay(coreThreadTimeOut);
   1971             long startTime = System.nanoTime();
   1972             while (p.getPoolSize() > 0
   1973                    && millisElapsedSince(startTime) < LONG_DELAY_MS)
   1974                 Thread.yield();
   1975             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
   1976             assertEquals(0, p.getPoolSize());
   1977         } finally {
   1978             joinPool(p);
   1979         }
   1980     }
   1981 
   1982     /**
   1983      * allowCoreThreadTimeOut(false) causes idle threads not to time out
   1984      */
   1985     public void testAllowCoreThreadTimeOut_false() throws Exception {
   1986         long coreThreadTimeOut = SHORT_DELAY_MS;
   1987         final ThreadPoolExecutor p =
   1988             new ThreadPoolExecutor(2, 10,
   1989                                    coreThreadTimeOut, MILLISECONDS,
   1990                                    new ArrayBlockingQueue<Runnable>(10));
   1991         final CountDownLatch threadStarted = new CountDownLatch(1);
   1992         try {
   1993             p.allowCoreThreadTimeOut(false);
   1994             p.execute(new CheckedRunnable() {
   1995                 public void realRun() throws InterruptedException {
   1996                     threadStarted.countDown();
   1997                     assertTrue(p.getPoolSize() >= 1);
   1998                 }});
   1999             delay(2 * coreThreadTimeOut);
   2000             assertTrue(p.getPoolSize() >= 1);
   2001         } finally {
   2002             joinPool(p);
   2003         }
   2004     }
   2005 
   2006     /**
   2007      * execute allows the same task to be submitted multiple times, even
   2008      * if rejected
   2009      */
   2010     public void testRejectedRecycledTask() throws InterruptedException {
   2011         final int nTasks = 1000;
   2012         final CountDownLatch done = new CountDownLatch(nTasks);
   2013         final Runnable recycledTask = new Runnable() {
   2014             public void run() {
   2015                 done.countDown();
   2016             }};
   2017         final ThreadPoolExecutor p =
   2018             new ThreadPoolExecutor(1, 30, 60, TimeUnit.SECONDS,
   2019                                    new ArrayBlockingQueue(30));
   2020         try {
   2021             for (int i = 0; i < nTasks; ++i) {
   2022                 for (;;) {
   2023                     try {
   2024                         p.execute(recycledTask);
   2025                         break;
   2026                     }
   2027                     catch (RejectedExecutionException ignore) {}
   2028                 }
   2029             }
   2030             // enough time to run all tasks
   2031             assertTrue(done.await(nTasks * SHORT_DELAY_MS, MILLISECONDS));
   2032         } finally {
   2033             joinPool(p);
   2034         }
   2035     }
   2036 
   2037 }
   2038