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