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