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