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