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