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 {
main(String[] args)71     public static void main(String[] args) {
72         main(suite(), args);
73     }
suite()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 
ExtendedTPE()83         public ExtendedTPE() {
84             super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
85         }
beforeExecute(Thread t, Runnable r)86         protected void beforeExecute(Thread t, Runnable r) {
87             beforeCalled.countDown();
88         }
afterExecute(Runnable r, Throwable t)89         protected void afterExecute(Runnable r, Throwable t) {
90             afterCalled.countDown();
91         }
terminated()92         protected void terminated() {
93             terminatedCalled.countDown();
94         }
95 
beforeCalled()96         public boolean beforeCalled() {
97             return beforeCalled.getCount() == 0;
98         }
afterCalled()99         public boolean afterCalled() {
100             return afterCalled.getCount() == 0;
101         }
terminatedCalled()102         public boolean terminatedCalled() {
103             return terminatedCalled.getCount() == 0;
104         }
105     }
106 
107     static class FailingThreadFactory implements ThreadFactory {
108         int calls = 0;
newThread(Runnable r)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      */
testExecute()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      */
testGetActiveCount()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      */
testPrestartCoreThread()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      */
testPrestartAllCoreThreads()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      */
testGetCompletedTaskCount()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      */
testGetCorePoolSize()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      */
testGetKeepAliveTime()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      */
testGetThreadFactory()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      */
testSetThreadFactory()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      */
testSetThreadFactoryNull()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      */
testDefaultRejectedExecutionHandler()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      */
testGetRejectedExecutionHandler()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      */
testSetRejectedExecutionHandler()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      */
testSetRejectedExecutionHandlerNull()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      */
testGetLargestPoolSize()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      */
testGetMaximumPoolSize()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      */
testGetPoolSize()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      */
testGetTaskCount()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      */
testIsShutdown()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      */
testAwaitTermination_timesOut()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      */
testIsTerminated()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      */
testIsTerminating()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      */
testGetQueue()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[] rtasks = new FutureTask[5];
594             @SuppressWarnings("unchecked")
595             FutureTask<Boolean>[] tasks = (FutureTask<Boolean>[])rtasks;
596             for (int i = 0; i < tasks.length; i++) {
597                 Callable<Boolean> task = new CheckedCallable<>() {
598                     public Boolean realCall() throws InterruptedException {
599                         threadStarted.countDown();
600                         assertSame(q, p.getQueue());
601                         await(done);
602                         return Boolean.TRUE;
603                     }};
604                 tasks[i] = new FutureTask<>(task);
605                 p.execute(tasks[i]);
606             }
607             await(threadStarted);
608             assertSame(q, p.getQueue());
609             assertFalse(q.contains(tasks[0]));
610             assertTrue(q.contains(tasks[tasks.length - 1]));
611             assertEquals(tasks.length - 1, q.size());
612         }
613     }
614 
615     /**
616      * remove(task) removes queued task, and fails to remove active task
617      */
testRemove()618     public void testRemove() throws InterruptedException {
619         final CountDownLatch done = new CountDownLatch(1);
620         BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
621         final ThreadPoolExecutor p =
622             new ThreadPoolExecutor(1, 1,
623                                    LONG_DELAY_MS, MILLISECONDS,
624                                    q);
625         try (PoolCleaner cleaner = cleaner(p, done)) {
626             Runnable[] tasks = new Runnable[6];
627             final CountDownLatch threadStarted = new CountDownLatch(1);
628             for (int i = 0; i < tasks.length; i++) {
629                 tasks[i] = new CheckedRunnable() {
630                     public void realRun() throws InterruptedException {
631                         threadStarted.countDown();
632                         await(done);
633                     }};
634                 p.execute(tasks[i]);
635             }
636             await(threadStarted);
637             assertFalse(p.remove(tasks[0]));
638             assertTrue(q.contains(tasks[4]));
639             assertTrue(q.contains(tasks[3]));
640             assertTrue(p.remove(tasks[4]));
641             assertFalse(p.remove(tasks[4]));
642             assertFalse(q.contains(tasks[4]));
643             assertTrue(q.contains(tasks[3]));
644             assertTrue(p.remove(tasks[3]));
645             assertFalse(q.contains(tasks[3]));
646         }
647     }
648 
649     /**
650      * purge removes cancelled tasks from the queue
651      */
testPurge()652     public void testPurge() throws InterruptedException {
653         final CountDownLatch threadStarted = new CountDownLatch(1);
654         final CountDownLatch done = new CountDownLatch(1);
655         final BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
656         final ThreadPoolExecutor p =
657             new ThreadPoolExecutor(1, 1,
658                                    LONG_DELAY_MS, MILLISECONDS,
659                                    q);
660         try (PoolCleaner cleaner = cleaner(p, done)) {
661             FutureTask[] rtasks = new FutureTask[5];
662             @SuppressWarnings("unchecked")
663             FutureTask<Boolean>[] tasks = (FutureTask<Boolean>[])rtasks;
664             for (int i = 0; i < tasks.length; i++) {
665                 Callable<Boolean> task = new CheckedCallable<>() {
666                     public Boolean realCall() throws InterruptedException {
667                         threadStarted.countDown();
668                         await(done);
669                         return Boolean.TRUE;
670                     }};
671                 tasks[i] = new FutureTask<>(task);
672                 p.execute(tasks[i]);
673             }
674             await(threadStarted);
675             assertEquals(tasks.length, p.getTaskCount());
676             assertEquals(tasks.length - 1, q.size());
677             assertEquals(1L, p.getActiveCount());
678             assertEquals(0L, p.getCompletedTaskCount());
679             tasks[4].cancel(true);
680             tasks[3].cancel(false);
681             p.purge();
682             assertEquals(tasks.length - 3, q.size());
683             assertEquals(tasks.length - 2, p.getTaskCount());
684             p.purge();         // Nothing to do
685             assertEquals(tasks.length - 3, q.size());
686             assertEquals(tasks.length - 2, p.getTaskCount());
687         }
688     }
689 
690     /**
691      * shutdownNow returns a list containing tasks that were not run,
692      * and those tasks are drained from the queue
693      */
testShutdownNow()694     public void testShutdownNow() throws InterruptedException {
695         final int poolSize = 2;
696         final int count = 5;
697         final AtomicInteger ran = new AtomicInteger(0);
698         final ThreadPoolExecutor p =
699             new ThreadPoolExecutor(poolSize, poolSize,
700                                    LONG_DELAY_MS, MILLISECONDS,
701                                    new ArrayBlockingQueue<Runnable>(10));
702         final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
703         Runnable waiter = new CheckedRunnable() { public void realRun() {
704             threadsStarted.countDown();
705             try {
706                 MILLISECONDS.sleep(LONGER_DELAY_MS);
707             } catch (InterruptedException success) {}
708             ran.getAndIncrement();
709         }};
710         for (int i = 0; i < count; i++)
711             p.execute(waiter);
712         await(threadsStarted);
713         assertEquals(poolSize, p.getActiveCount());
714         assertEquals(0, p.getCompletedTaskCount());
715         final List<Runnable> queuedTasks;
716         try {
717             queuedTasks = p.shutdownNow();
718         } catch (SecurityException ok) {
719             return; // Allowed in case test doesn't have privs
720         }
721         assertTrue(p.isShutdown());
722         assertTrue(p.getQueue().isEmpty());
723         assertEquals(count - poolSize, queuedTasks.size());
724         assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
725         assertTrue(p.isTerminated());
726         assertEquals(poolSize, ran.get());
727         assertEquals(poolSize, p.getCompletedTaskCount());
728     }
729 
730     // Exception Tests
731 
732     /**
733      * Constructor throws if corePoolSize argument is less than zero
734      */
testConstructor1()735     public void testConstructor1() {
736         try {
737             new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
738                                    new ArrayBlockingQueue<Runnable>(10));
739             shouldThrow();
740         } catch (IllegalArgumentException success) {}
741     }
742 
743     /**
744      * Constructor throws if maximumPoolSize is less than zero
745      */
testConstructor2()746     public void testConstructor2() {
747         try {
748             new ThreadPoolExecutor(1, -1, 1L, SECONDS,
749                                    new ArrayBlockingQueue<Runnable>(10));
750             shouldThrow();
751         } catch (IllegalArgumentException success) {}
752     }
753 
754     /**
755      * Constructor throws if maximumPoolSize is equal to zero
756      */
testConstructor3()757     public void testConstructor3() {
758         try {
759             new ThreadPoolExecutor(1, 0, 1L, SECONDS,
760                                    new ArrayBlockingQueue<Runnable>(10));
761             shouldThrow();
762         } catch (IllegalArgumentException success) {}
763     }
764 
765     /**
766      * Constructor throws if keepAliveTime is less than zero
767      */
testConstructor4()768     public void testConstructor4() {
769         try {
770             new ThreadPoolExecutor(1, 2, -1L, SECONDS,
771                                    new ArrayBlockingQueue<Runnable>(10));
772             shouldThrow();
773         } catch (IllegalArgumentException success) {}
774     }
775 
776     /**
777      * Constructor throws if corePoolSize is greater than the maximumPoolSize
778      */
testConstructor5()779     public void testConstructor5() {
780         try {
781             new ThreadPoolExecutor(2, 1, 1L, SECONDS,
782                                    new ArrayBlockingQueue<Runnable>(10));
783             shouldThrow();
784         } catch (IllegalArgumentException success) {}
785     }
786 
787     /**
788      * Constructor throws if workQueue is set to null
789      */
testConstructorNullPointerException()790     public void testConstructorNullPointerException() {
791         try {
792             new ThreadPoolExecutor(1, 2, 1L, SECONDS,
793                                    (BlockingQueue<Runnable>) null);
794             shouldThrow();
795         } catch (NullPointerException success) {}
796     }
797 
798     /**
799      * Constructor throws if corePoolSize argument is less than zero
800      */
testConstructor6()801     public void testConstructor6() {
802         try {
803             new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
804                                    new ArrayBlockingQueue<Runnable>(10),
805                                    new SimpleThreadFactory());
806             shouldThrow();
807         } catch (IllegalArgumentException success) {}
808     }
809 
810     /**
811      * Constructor throws if maximumPoolSize is less than zero
812      */
testConstructor7()813     public void testConstructor7() {
814         try {
815             new ThreadPoolExecutor(1, -1, 1L, SECONDS,
816                                    new ArrayBlockingQueue<Runnable>(10),
817                                    new SimpleThreadFactory());
818             shouldThrow();
819         } catch (IllegalArgumentException success) {}
820     }
821 
822     /**
823      * Constructor throws if maximumPoolSize is equal to zero
824      */
testConstructor8()825     public void testConstructor8() {
826         try {
827             new ThreadPoolExecutor(1, 0, 1L, SECONDS,
828                                    new ArrayBlockingQueue<Runnable>(10),
829                                    new SimpleThreadFactory());
830             shouldThrow();
831         } catch (IllegalArgumentException success) {}
832     }
833 
834     /**
835      * Constructor throws if keepAliveTime is less than zero
836      */
testConstructor9()837     public void testConstructor9() {
838         try {
839             new ThreadPoolExecutor(1, 2, -1L, SECONDS,
840                                    new ArrayBlockingQueue<Runnable>(10),
841                                    new SimpleThreadFactory());
842             shouldThrow();
843         } catch (IllegalArgumentException success) {}
844     }
845 
846     /**
847      * Constructor throws if corePoolSize is greater than the maximumPoolSize
848      */
testConstructor10()849     public void testConstructor10() {
850         try {
851             new ThreadPoolExecutor(2, 1, 1L, SECONDS,
852                                    new ArrayBlockingQueue<Runnable>(10),
853                                    new SimpleThreadFactory());
854             shouldThrow();
855         } catch (IllegalArgumentException success) {}
856     }
857 
858     /**
859      * Constructor throws if workQueue is set to null
860      */
testConstructorNullPointerException2()861     public void testConstructorNullPointerException2() {
862         try {
863             new ThreadPoolExecutor(1, 2, 1L, SECONDS,
864                                    (BlockingQueue<Runnable>) null,
865                                    new SimpleThreadFactory());
866             shouldThrow();
867         } catch (NullPointerException success) {}
868     }
869 
870     /**
871      * Constructor throws if threadFactory is set to null
872      */
testConstructorNullPointerException3()873     public void testConstructorNullPointerException3() {
874         try {
875             new ThreadPoolExecutor(1, 2, 1L, SECONDS,
876                                    new ArrayBlockingQueue<Runnable>(10),
877                                    (ThreadFactory) null);
878             shouldThrow();
879         } catch (NullPointerException success) {}
880     }
881 
882     /**
883      * Constructor throws if corePoolSize argument is less than zero
884      */
testConstructor11()885     public void testConstructor11() {
886         try {
887             new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
888                                    new ArrayBlockingQueue<Runnable>(10),
889                                    new NoOpREHandler());
890             shouldThrow();
891         } catch (IllegalArgumentException success) {}
892     }
893 
894     /**
895      * Constructor throws if maximumPoolSize is less than zero
896      */
testConstructor12()897     public void testConstructor12() {
898         try {
899             new ThreadPoolExecutor(1, -1, 1L, SECONDS,
900                                    new ArrayBlockingQueue<Runnable>(10),
901                                    new NoOpREHandler());
902             shouldThrow();
903         } catch (IllegalArgumentException success) {}
904     }
905 
906     /**
907      * Constructor throws if maximumPoolSize is equal to zero
908      */
testConstructor13()909     public void testConstructor13() {
910         try {
911             new ThreadPoolExecutor(1, 0, 1L, SECONDS,
912                                    new ArrayBlockingQueue<Runnable>(10),
913                                    new NoOpREHandler());
914             shouldThrow();
915         } catch (IllegalArgumentException success) {}
916     }
917 
918     /**
919      * Constructor throws if keepAliveTime is less than zero
920      */
testConstructor14()921     public void testConstructor14() {
922         try {
923             new ThreadPoolExecutor(1, 2, -1L, SECONDS,
924                                    new ArrayBlockingQueue<Runnable>(10),
925                                    new NoOpREHandler());
926             shouldThrow();
927         } catch (IllegalArgumentException success) {}
928     }
929 
930     /**
931      * Constructor throws if corePoolSize is greater than the maximumPoolSize
932      */
testConstructor15()933     public void testConstructor15() {
934         try {
935             new ThreadPoolExecutor(2, 1, 1L, SECONDS,
936                                    new ArrayBlockingQueue<Runnable>(10),
937                                    new NoOpREHandler());
938             shouldThrow();
939         } catch (IllegalArgumentException success) {}
940     }
941 
942     /**
943      * Constructor throws if workQueue is set to null
944      */
testConstructorNullPointerException4()945     public void testConstructorNullPointerException4() {
946         try {
947             new ThreadPoolExecutor(1, 2, 1L, SECONDS,
948                                    (BlockingQueue<Runnable>) null,
949                                    new NoOpREHandler());
950             shouldThrow();
951         } catch (NullPointerException success) {}
952     }
953 
954     /**
955      * Constructor throws if handler is set to null
956      */
testConstructorNullPointerException5()957     public void testConstructorNullPointerException5() {
958         try {
959             new ThreadPoolExecutor(1, 2, 1L, SECONDS,
960                                    new ArrayBlockingQueue<Runnable>(10),
961                                    (RejectedExecutionHandler) null);
962             shouldThrow();
963         } catch (NullPointerException success) {}
964     }
965 
966     /**
967      * Constructor throws if corePoolSize argument is less than zero
968      */
testConstructor16()969     public void testConstructor16() {
970         try {
971             new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
972                                    new ArrayBlockingQueue<Runnable>(10),
973                                    new SimpleThreadFactory(),
974                                    new NoOpREHandler());
975             shouldThrow();
976         } catch (IllegalArgumentException success) {}
977     }
978 
979     /**
980      * Constructor throws if maximumPoolSize is less than zero
981      */
testConstructor17()982     public void testConstructor17() {
983         try {
984             new ThreadPoolExecutor(1, -1, 1L, SECONDS,
985                                    new ArrayBlockingQueue<Runnable>(10),
986                                    new SimpleThreadFactory(),
987                                    new NoOpREHandler());
988             shouldThrow();
989         } catch (IllegalArgumentException success) {}
990     }
991 
992     /**
993      * Constructor throws if maximumPoolSize is equal to zero
994      */
testConstructor18()995     public void testConstructor18() {
996         try {
997             new ThreadPoolExecutor(1, 0, 1L, SECONDS,
998                                    new ArrayBlockingQueue<Runnable>(10),
999                                    new SimpleThreadFactory(),
1000                                    new NoOpREHandler());
1001             shouldThrow();
1002         } catch (IllegalArgumentException success) {}
1003     }
1004 
1005     /**
1006      * Constructor throws if keepAliveTime is less than zero
1007      */
testConstructor19()1008     public void testConstructor19() {
1009         try {
1010             new ThreadPoolExecutor(1, 2, -1L, SECONDS,
1011                                    new ArrayBlockingQueue<Runnable>(10),
1012                                    new SimpleThreadFactory(),
1013                                    new NoOpREHandler());
1014             shouldThrow();
1015         } catch (IllegalArgumentException success) {}
1016     }
1017 
1018     /**
1019      * Constructor throws if corePoolSize is greater than the maximumPoolSize
1020      */
testConstructor20()1021     public void testConstructor20() {
1022         try {
1023             new ThreadPoolExecutor(2, 1, 1L, SECONDS,
1024                                    new ArrayBlockingQueue<Runnable>(10),
1025                                    new SimpleThreadFactory(),
1026                                    new NoOpREHandler());
1027             shouldThrow();
1028         } catch (IllegalArgumentException success) {}
1029     }
1030 
1031     /**
1032      * Constructor throws if workQueue is null
1033      */
testConstructorNullPointerException6()1034     public void testConstructorNullPointerException6() {
1035         try {
1036             new ThreadPoolExecutor(1, 2, 1L, SECONDS,
1037                                    (BlockingQueue<Runnable>) null,
1038                                    new SimpleThreadFactory(),
1039                                    new NoOpREHandler());
1040             shouldThrow();
1041         } catch (NullPointerException success) {}
1042     }
1043 
1044     /**
1045      * Constructor throws if handler is null
1046      */
testConstructorNullPointerException7()1047     public void testConstructorNullPointerException7() {
1048         try {
1049             new ThreadPoolExecutor(1, 2, 1L, SECONDS,
1050                                    new ArrayBlockingQueue<Runnable>(10),
1051                                    new SimpleThreadFactory(),
1052                                    (RejectedExecutionHandler) null);
1053             shouldThrow();
1054         } catch (NullPointerException success) {}
1055     }
1056 
1057     /**
1058      * Constructor throws if ThreadFactory is null
1059      */
testConstructorNullPointerException8()1060     public void testConstructorNullPointerException8() {
1061         try {
1062             new ThreadPoolExecutor(1, 2, 1L, SECONDS,
1063                                    new ArrayBlockingQueue<Runnable>(10),
1064                                    (ThreadFactory) null,
1065                                    new NoOpREHandler());
1066             shouldThrow();
1067         } catch (NullPointerException success) {}
1068     }
1069 
1070     /**
1071      * get of submitted callable throws InterruptedException if interrupted
1072      */
testInterruptedSubmit()1073     public void testInterruptedSubmit() throws InterruptedException {
1074         final CountDownLatch done = new CountDownLatch(1);
1075         final ThreadPoolExecutor p =
1076             new ThreadPoolExecutor(1, 1,
1077                                    60, SECONDS,
1078                                    new ArrayBlockingQueue<Runnable>(10));
1079 
1080         try (PoolCleaner cleaner = cleaner(p, done)) {
1081             final CountDownLatch threadStarted = new CountDownLatch(1);
1082             Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1083                 public void realRun() throws Exception {
1084                     Callable<Boolean> task = new CheckedCallable<>() {
1085                         public Boolean realCall() throws InterruptedException {
1086                             threadStarted.countDown();
1087                             await(done);
1088                             return Boolean.TRUE;
1089                         }};
1090                     p.submit(task).get();
1091                 }});
1092 
1093             await(threadStarted); // ensure quiescence
1094             t.interrupt();
1095             awaitTermination(t);
1096         }
1097     }
1098 
1099     /**
1100      * Submitted tasks are rejected when saturated or shutdown
1101      */
testSubmittedTasksRejectedWhenSaturatedOrShutdown()1102     public void testSubmittedTasksRejectedWhenSaturatedOrShutdown() throws InterruptedException {
1103         final ThreadPoolExecutor p = new ThreadPoolExecutor(
1104             1, 1, 1, SECONDS, new ArrayBlockingQueue<Runnable>(1));
1105         final int saturatedSize = saturatedSize(p);
1106         final ThreadLocalRandom rnd = ThreadLocalRandom.current();
1107         final CountDownLatch threadsStarted = new CountDownLatch(p.getMaximumPoolSize());
1108         final CountDownLatch done = new CountDownLatch(1);
1109         final Runnable r = () -> {
1110             threadsStarted.countDown();
1111             for (;;) {
1112                 try {
1113                     done.await();
1114                     return;
1115                 } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
1116             }};
1117         final Callable<Boolean> c = () -> {
1118             threadsStarted.countDown();
1119             for (;;) {
1120                 try {
1121                     done.await();
1122                     return Boolean.TRUE;
1123                 } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
1124             }};
1125         final boolean shutdownNow = rnd.nextBoolean();
1126 
1127         try (PoolCleaner cleaner = cleaner(p, done)) {
1128             // saturate
1129             for (int i = saturatedSize; i--> 0; ) {
1130                 switch (rnd.nextInt(4)) {
1131                 case 0: p.execute(r); break;
1132                 case 1: assertFalse(p.submit(r).isDone()); break;
1133                 case 2: assertFalse(p.submit(r, Boolean.TRUE).isDone()); break;
1134                 case 3: assertFalse(p.submit(c).isDone()); break;
1135                 }
1136             }
1137 
1138             await(threadsStarted);
1139             assertTaskSubmissionsAreRejected(p);
1140 
1141             if (shutdownNow)
1142                 p.shutdownNow();
1143             else
1144                 p.shutdown();
1145             // Pool is shutdown, but not yet terminated
1146             assertTaskSubmissionsAreRejected(p);
1147             assertFalse(p.isTerminated());
1148 
1149             done.countDown();   // release blocking tasks
1150             assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
1151 
1152             assertTaskSubmissionsAreRejected(p);
1153         }
1154         assertEquals(saturatedSize(p)
1155                      - (shutdownNow ? p.getQueue().remainingCapacity() : 0),
1156                      p.getCompletedTaskCount());
1157     }
1158 
1159     /**
1160      * executor using DiscardOldestPolicy drops oldest task if saturated.
1161      */
testSaturatedExecute_DiscardOldestPolicy()1162     public void testSaturatedExecute_DiscardOldestPolicy() {
1163         final CountDownLatch done = new CountDownLatch(1);
1164         LatchAwaiter r1 = awaiter(done);
1165         LatchAwaiter r2 = awaiter(done);
1166         LatchAwaiter r3 = awaiter(done);
1167         final ThreadPoolExecutor p =
1168             new ThreadPoolExecutor(1, 1,
1169                                    LONG_DELAY_MS, MILLISECONDS,
1170                                    new ArrayBlockingQueue<Runnable>(1),
1171                                    new DiscardOldestPolicy());
1172         try (PoolCleaner cleaner = cleaner(p, done)) {
1173             assertEquals(LatchAwaiter.NEW, r1.state);
1174             assertEquals(LatchAwaiter.NEW, r2.state);
1175             assertEquals(LatchAwaiter.NEW, r3.state);
1176             p.execute(r1);
1177             p.execute(r2);
1178             assertTrue(p.getQueue().contains(r2));
1179             p.execute(r3);
1180             assertFalse(p.getQueue().contains(r2));
1181             assertTrue(p.getQueue().contains(r3));
1182         }
1183         assertEquals(LatchAwaiter.DONE, r1.state);
1184         assertEquals(LatchAwaiter.NEW, r2.state);
1185         assertEquals(LatchAwaiter.DONE, r3.state);
1186     }
1187 
1188     /**
1189      * execute using DiscardOldestPolicy drops task on shutdown
1190      */
testDiscardOldestOnShutdown()1191     public void testDiscardOldestOnShutdown() {
1192         final ThreadPoolExecutor p =
1193             new ThreadPoolExecutor(1, 1,
1194                                    LONG_DELAY_MS, MILLISECONDS,
1195                                    new ArrayBlockingQueue<Runnable>(1),
1196                                    new DiscardOldestPolicy());
1197 
1198         try { p.shutdown(); } catch (SecurityException ok) { return; }
1199         try (PoolCleaner cleaner = cleaner(p)) {
1200             TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1201             p.execute(r);
1202             assertFalse(r.done);
1203         }
1204     }
1205 
1206     /**
1207      * Submitting null tasks throws NullPointerException
1208      */
testNullTaskSubmission()1209     public void testNullTaskSubmission() {
1210         final ThreadPoolExecutor p =
1211             new ThreadPoolExecutor(1, 2,
1212                                    1L, SECONDS,
1213                                    new ArrayBlockingQueue<Runnable>(10));
1214         try (PoolCleaner cleaner = cleaner(p)) {
1215             assertNullTaskSubmissionThrowsNullPointerException(p);
1216         }
1217     }
1218 
1219     /**
1220      * setCorePoolSize of negative value throws IllegalArgumentException
1221      */
testCorePoolSizeIllegalArgumentException()1222     public void testCorePoolSizeIllegalArgumentException() {
1223         final ThreadPoolExecutor p =
1224             new ThreadPoolExecutor(1, 2,
1225                                    LONG_DELAY_MS, MILLISECONDS,
1226                                    new ArrayBlockingQueue<Runnable>(10));
1227         try (PoolCleaner cleaner = cleaner(p)) {
1228             try {
1229                 p.setCorePoolSize(-1);
1230                 shouldThrow();
1231             } catch (IllegalArgumentException success) {}
1232         }
1233     }
1234 
1235     /**
1236      * setMaximumPoolSize(int) throws IllegalArgumentException if
1237      * given a value less the core pool size
1238      */
testMaximumPoolSizeIllegalArgumentException()1239     public void testMaximumPoolSizeIllegalArgumentException() {
1240         final ThreadPoolExecutor p =
1241             new ThreadPoolExecutor(2, 3,
1242                                    LONG_DELAY_MS, MILLISECONDS,
1243                                    new ArrayBlockingQueue<Runnable>(10));
1244         try (PoolCleaner cleaner = cleaner(p)) {
1245             try {
1246                 p.setMaximumPoolSize(1);
1247                 shouldThrow();
1248             } catch (IllegalArgumentException success) {}
1249         }
1250     }
1251 
1252     /**
1253      * setMaximumPoolSize throws IllegalArgumentException
1254      * if given a negative value
1255      */
testMaximumPoolSizeIllegalArgumentException2()1256     public void testMaximumPoolSizeIllegalArgumentException2() {
1257         final ThreadPoolExecutor p =
1258             new ThreadPoolExecutor(2, 3,
1259                                    LONG_DELAY_MS, MILLISECONDS,
1260                                    new ArrayBlockingQueue<Runnable>(10));
1261         try (PoolCleaner cleaner = cleaner(p)) {
1262             try {
1263                 p.setMaximumPoolSize(-1);
1264                 shouldThrow();
1265             } catch (IllegalArgumentException success) {}
1266         }
1267     }
1268 
1269     /**
1270      * Configuration changes that allow core pool size greater than
1271      * max pool size result in IllegalArgumentException.
1272      */
testPoolSizeInvariants()1273     public void testPoolSizeInvariants() {
1274         final ThreadPoolExecutor p =
1275             new ThreadPoolExecutor(1, 1,
1276                                    LONG_DELAY_MS, MILLISECONDS,
1277                                    new ArrayBlockingQueue<Runnable>(10));
1278         try (PoolCleaner cleaner = cleaner(p)) {
1279             for (int s = 1; s < 5; s++) {
1280                 p.setMaximumPoolSize(s);
1281                 p.setCorePoolSize(s);
1282                 try {
1283                     p.setMaximumPoolSize(s - 1);
1284                     shouldThrow();
1285                 } catch (IllegalArgumentException success) {}
1286                 assertEquals(s, p.getCorePoolSize());
1287                 assertEquals(s, p.getMaximumPoolSize());
1288                 try {
1289                     p.setCorePoolSize(s + 1);
1290                     shouldThrow();
1291                 } catch (IllegalArgumentException success) {}
1292                 assertEquals(s, p.getCorePoolSize());
1293                 assertEquals(s, p.getMaximumPoolSize());
1294             }
1295         }
1296     }
1297 
1298     /**
1299      * setKeepAliveTime throws IllegalArgumentException
1300      * when given a negative value
1301      */
testKeepAliveTimeIllegalArgumentException()1302     public void testKeepAliveTimeIllegalArgumentException() {
1303         final ThreadPoolExecutor p =
1304             new ThreadPoolExecutor(2, 3,
1305                                    LONG_DELAY_MS, MILLISECONDS,
1306                                    new ArrayBlockingQueue<Runnable>(10));
1307         try (PoolCleaner cleaner = cleaner(p)) {
1308             try {
1309                 p.setKeepAliveTime(-1, MILLISECONDS);
1310                 shouldThrow();
1311             } catch (IllegalArgumentException success) {}
1312         }
1313     }
1314 
1315     /**
1316      * terminated() is called on termination
1317      */
testTerminated()1318     public void testTerminated() {
1319         ExtendedTPE p = new ExtendedTPE();
1320         try (PoolCleaner cleaner = cleaner(p)) {
1321             try { p.shutdown(); } catch (SecurityException ok) { return; }
1322             assertTrue(p.terminatedCalled());
1323             assertTrue(p.isShutdown());
1324         }
1325     }
1326 
1327     /**
1328      * beforeExecute and afterExecute are called when executing task
1329      */
testBeforeAfter()1330     public void testBeforeAfter() throws InterruptedException {
1331         ExtendedTPE p = new ExtendedTPE();
1332         try (PoolCleaner cleaner = cleaner(p)) {
1333             final CountDownLatch done = new CountDownLatch(1);
1334             p.execute(new CheckedRunnable() {
1335                 public void realRun() {
1336                     done.countDown();
1337                 }});
1338             await(p.afterCalled);
1339             assertEquals(0, done.getCount());
1340             assertTrue(p.afterCalled());
1341             assertTrue(p.beforeCalled());
1342         }
1343     }
1344 
1345     /**
1346      * completed submit of callable returns result
1347      */
testSubmitCallable()1348     public void testSubmitCallable() throws Exception {
1349         final ExecutorService e =
1350             new ThreadPoolExecutor(2, 2,
1351                                    LONG_DELAY_MS, MILLISECONDS,
1352                                    new ArrayBlockingQueue<Runnable>(10));
1353         try (PoolCleaner cleaner = cleaner(e)) {
1354             Future<String> future = e.submit(new StringTask());
1355             String result = future.get();
1356             assertSame(TEST_STRING, result);
1357         }
1358     }
1359 
1360     /**
1361      * completed submit of runnable returns successfully
1362      */
testSubmitRunnable()1363     public void testSubmitRunnable() throws Exception {
1364         final ExecutorService e =
1365             new ThreadPoolExecutor(2, 2,
1366                                    LONG_DELAY_MS, MILLISECONDS,
1367                                    new ArrayBlockingQueue<Runnable>(10));
1368         try (PoolCleaner cleaner = cleaner(e)) {
1369             Future<?> future = e.submit(new NoOpRunnable());
1370             future.get();
1371             assertTrue(future.isDone());
1372         }
1373     }
1374 
1375     /**
1376      * completed submit of (runnable, result) returns result
1377      */
testSubmitRunnable2()1378     public void testSubmitRunnable2() throws Exception {
1379         final ExecutorService e =
1380             new ThreadPoolExecutor(2, 2,
1381                                    LONG_DELAY_MS, MILLISECONDS,
1382                                    new ArrayBlockingQueue<Runnable>(10));
1383         try (PoolCleaner cleaner = cleaner(e)) {
1384             Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
1385             String result = future.get();
1386             assertSame(TEST_STRING, result);
1387         }
1388     }
1389 
1390     /**
1391      * invokeAny(null) throws NPE
1392      */
testInvokeAny1()1393     public void testInvokeAny1() throws Exception {
1394         final ExecutorService e =
1395             new ThreadPoolExecutor(2, 2,
1396                                    LONG_DELAY_MS, MILLISECONDS,
1397                                    new ArrayBlockingQueue<Runnable>(10));
1398         try (PoolCleaner cleaner = cleaner(e)) {
1399             try {
1400                 e.invokeAny(null);
1401                 shouldThrow();
1402             } catch (NullPointerException success) {}
1403         }
1404     }
1405 
1406     /**
1407      * invokeAny(empty collection) throws IllegalArgumentException
1408      */
testInvokeAny2()1409     public void testInvokeAny2() throws Exception {
1410         final ExecutorService e =
1411             new ThreadPoolExecutor(2, 2,
1412                                    LONG_DELAY_MS, MILLISECONDS,
1413                                    new ArrayBlockingQueue<Runnable>(10));
1414         try (PoolCleaner cleaner = cleaner(e)) {
1415             try {
1416                 e.invokeAny(new ArrayList<Callable<String>>());
1417                 shouldThrow();
1418             } catch (IllegalArgumentException success) {}
1419         }
1420     }
1421 
1422     /**
1423      * invokeAny(c) throws NPE if c has null elements
1424      */
testInvokeAny3()1425     public void testInvokeAny3() throws Exception {
1426         final CountDownLatch latch = new CountDownLatch(1);
1427         final ExecutorService e =
1428             new ThreadPoolExecutor(2, 2,
1429                                    LONG_DELAY_MS, MILLISECONDS,
1430                                    new ArrayBlockingQueue<Runnable>(10));
1431         try (PoolCleaner cleaner = cleaner(e)) {
1432             List<Callable<String>> l = new ArrayList<>();
1433             l.add(latchAwaitingStringTask(latch));
1434             l.add(null);
1435             try {
1436                 e.invokeAny(l);
1437                 shouldThrow();
1438             } catch (NullPointerException success) {}
1439             latch.countDown();
1440         }
1441     }
1442 
1443     /**
1444      * invokeAny(c) throws ExecutionException if no task completes
1445      */
testInvokeAny4()1446     public void testInvokeAny4() throws Exception {
1447         final ExecutorService e =
1448             new ThreadPoolExecutor(2, 2,
1449                                    LONG_DELAY_MS, MILLISECONDS,
1450                                    new ArrayBlockingQueue<Runnable>(10));
1451         try (PoolCleaner cleaner = cleaner(e)) {
1452             List<Callable<String>> l = new ArrayList<>();
1453             l.add(new NPETask());
1454             try {
1455                 e.invokeAny(l);
1456                 shouldThrow();
1457             } catch (ExecutionException success) {
1458                 assertTrue(success.getCause() instanceof NullPointerException);
1459             }
1460         }
1461     }
1462 
1463     /**
1464      * invokeAny(c) returns result of some task
1465      */
testInvokeAny5()1466     public void testInvokeAny5() throws Exception {
1467         final ExecutorService e =
1468             new ThreadPoolExecutor(2, 2,
1469                                    LONG_DELAY_MS, MILLISECONDS,
1470                                    new ArrayBlockingQueue<Runnable>(10));
1471         try (PoolCleaner cleaner = cleaner(e)) {
1472             List<Callable<String>> l = new ArrayList<>();
1473             l.add(new StringTask());
1474             l.add(new StringTask());
1475             String result = e.invokeAny(l);
1476             assertSame(TEST_STRING, result);
1477         }
1478     }
1479 
1480     /**
1481      * invokeAll(null) throws NPE
1482      */
testInvokeAll1()1483     public void testInvokeAll1() throws Exception {
1484         final ExecutorService e =
1485             new ThreadPoolExecutor(2, 2,
1486                                    LONG_DELAY_MS, MILLISECONDS,
1487                                    new ArrayBlockingQueue<Runnable>(10));
1488         try (PoolCleaner cleaner = cleaner(e)) {
1489             try {
1490                 e.invokeAll(null);
1491                 shouldThrow();
1492             } catch (NullPointerException success) {}
1493         }
1494     }
1495 
1496     /**
1497      * invokeAll(empty collection) returns empty list
1498      */
testInvokeAll2()1499     public void testInvokeAll2() throws InterruptedException {
1500         final ExecutorService e =
1501             new ThreadPoolExecutor(2, 2,
1502                                    LONG_DELAY_MS, MILLISECONDS,
1503                                    new ArrayBlockingQueue<Runnable>(10));
1504         final Collection<Callable<String>> emptyCollection
1505             = Collections.emptyList();
1506         try (PoolCleaner cleaner = cleaner(e)) {
1507             List<Future<String>> r = e.invokeAll(emptyCollection);
1508             assertTrue(r.isEmpty());
1509         }
1510     }
1511 
1512     /**
1513      * invokeAll(c) throws NPE if c has null elements
1514      */
testInvokeAll3()1515     public void testInvokeAll3() throws Exception {
1516         final ExecutorService e =
1517             new ThreadPoolExecutor(2, 2,
1518                                    LONG_DELAY_MS, MILLISECONDS,
1519                                    new ArrayBlockingQueue<Runnable>(10));
1520         try (PoolCleaner cleaner = cleaner(e)) {
1521             List<Callable<String>> l = new ArrayList<>();
1522             l.add(new StringTask());
1523             l.add(null);
1524             try {
1525                 e.invokeAll(l);
1526                 shouldThrow();
1527             } catch (NullPointerException success) {}
1528         }
1529     }
1530 
1531     /**
1532      * get of element of invokeAll(c) throws exception on failed task
1533      */
testInvokeAll4()1534     public void testInvokeAll4() throws Exception {
1535         final ExecutorService e =
1536             new ThreadPoolExecutor(2, 2,
1537                                    LONG_DELAY_MS, MILLISECONDS,
1538                                    new ArrayBlockingQueue<Runnable>(10));
1539         try (PoolCleaner cleaner = cleaner(e)) {
1540             List<Callable<String>> l = new ArrayList<>();
1541             l.add(new NPETask());
1542             List<Future<String>> futures = e.invokeAll(l);
1543             assertEquals(1, futures.size());
1544             try {
1545                 futures.get(0).get();
1546                 shouldThrow();
1547             } catch (ExecutionException success) {
1548                 assertTrue(success.getCause() instanceof NullPointerException);
1549             }
1550         }
1551     }
1552 
1553     /**
1554      * invokeAll(c) returns results of all completed tasks
1555      */
testInvokeAll5()1556     public void testInvokeAll5() throws Exception {
1557         final ExecutorService e =
1558             new ThreadPoolExecutor(2, 2,
1559                                    LONG_DELAY_MS, MILLISECONDS,
1560                                    new ArrayBlockingQueue<Runnable>(10));
1561         try (PoolCleaner cleaner = cleaner(e)) {
1562             List<Callable<String>> l = new ArrayList<>();
1563             l.add(new StringTask());
1564             l.add(new StringTask());
1565             List<Future<String>> futures = e.invokeAll(l);
1566             assertEquals(2, futures.size());
1567             for (Future<String> future : futures)
1568                 assertSame(TEST_STRING, future.get());
1569         }
1570     }
1571 
1572     /**
1573      * timed invokeAny(null) throws NPE
1574      */
testTimedInvokeAny1()1575     public void testTimedInvokeAny1() throws Exception {
1576         final ExecutorService e =
1577             new ThreadPoolExecutor(2, 2,
1578                                    LONG_DELAY_MS, MILLISECONDS,
1579                                    new ArrayBlockingQueue<Runnable>(10));
1580         try (PoolCleaner cleaner = cleaner(e)) {
1581             try {
1582                 e.invokeAny(null, randomTimeout(), randomTimeUnit());
1583                 shouldThrow();
1584             } catch (NullPointerException success) {}
1585         }
1586     }
1587 
1588     /**
1589      * timed invokeAny(,,null) throws NPE
1590      */
testTimedInvokeAnyNullTimeUnit()1591     public void testTimedInvokeAnyNullTimeUnit() throws Exception {
1592         final ExecutorService e =
1593             new ThreadPoolExecutor(2, 2,
1594                                    LONG_DELAY_MS, MILLISECONDS,
1595                                    new ArrayBlockingQueue<Runnable>(10));
1596         try (PoolCleaner cleaner = cleaner(e)) {
1597             List<Callable<String>> l = new ArrayList<>();
1598             l.add(new StringTask());
1599             try {
1600                 e.invokeAny(l, randomTimeout(), null);
1601                 shouldThrow();
1602             } catch (NullPointerException success) {}
1603         }
1604     }
1605 
1606     /**
1607      * timed invokeAny(empty collection) throws IllegalArgumentException
1608      */
testTimedInvokeAny2()1609     public void testTimedInvokeAny2() throws Exception {
1610         final ExecutorService e =
1611             new ThreadPoolExecutor(2, 2,
1612                                    LONG_DELAY_MS, MILLISECONDS,
1613                                    new ArrayBlockingQueue<Runnable>(10));
1614         try (PoolCleaner cleaner = cleaner(e)) {
1615             try {
1616                 e.invokeAny(new ArrayList<Callable<String>>(),
1617                             randomTimeout(), randomTimeUnit());
1618                 shouldThrow();
1619             } catch (IllegalArgumentException success) {}
1620         }
1621     }
1622 
1623     /**
1624      * timed invokeAny(c) throws NullPointerException if c has null elements
1625      */
testTimedInvokeAny3()1626     public void testTimedInvokeAny3() throws Exception {
1627         final CountDownLatch latch = new CountDownLatch(1);
1628         final ExecutorService e =
1629             new ThreadPoolExecutor(2, 2,
1630                                    LONG_DELAY_MS, MILLISECONDS,
1631                                    new ArrayBlockingQueue<Runnable>(10));
1632         try (PoolCleaner cleaner = cleaner(e)) {
1633             List<Callable<String>> l = new ArrayList<>();
1634             l.add(latchAwaitingStringTask(latch));
1635             l.add(null);
1636             try {
1637                 e.invokeAny(l, randomTimeout(), randomTimeUnit());
1638                 shouldThrow();
1639             } catch (NullPointerException success) {}
1640             latch.countDown();
1641         }
1642     }
1643 
1644     /**
1645      * timed invokeAny(c) throws ExecutionException if no task completes
1646      */
testTimedInvokeAny4()1647     public void testTimedInvokeAny4() throws Exception {
1648         final ExecutorService e =
1649             new ThreadPoolExecutor(2, 2,
1650                                    LONG_DELAY_MS, MILLISECONDS,
1651                                    new ArrayBlockingQueue<Runnable>(10));
1652         try (PoolCleaner cleaner = cleaner(e)) {
1653             long startTime = System.nanoTime();
1654             List<Callable<String>> l = new ArrayList<>();
1655             l.add(new NPETask());
1656             try {
1657                 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1658                 shouldThrow();
1659             } catch (ExecutionException success) {
1660                 assertTrue(success.getCause() instanceof NullPointerException);
1661             }
1662             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1663         }
1664     }
1665 
1666     /**
1667      * timed invokeAny(c) returns result of some task
1668      */
1669     public void testTimedInvokeAny5() throws Exception {
1670         final ExecutorService e =
1671             new ThreadPoolExecutor(2, 2,
1672                                    LONG_DELAY_MS, MILLISECONDS,
1673                                    new ArrayBlockingQueue<Runnable>(10));
1674         try (PoolCleaner cleaner = cleaner(e)) {
1675             long startTime = System.nanoTime();
1676             List<Callable<String>> l = new ArrayList<>();
1677             l.add(new StringTask());
1678             l.add(new StringTask());
1679             String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1680             assertSame(TEST_STRING, result);
1681             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1682         }
1683     }
1684 
1685     /**
1686      * timed invokeAll(null) throws NPE
1687      */
1688     public void testTimedInvokeAll1() throws Exception {
1689         final ExecutorService e =
1690             new ThreadPoolExecutor(2, 2,
1691                                    LONG_DELAY_MS, MILLISECONDS,
1692                                    new ArrayBlockingQueue<Runnable>(10));
1693         try (PoolCleaner cleaner = cleaner(e)) {
1694             try {
1695                 e.invokeAll(null, randomTimeout(), randomTimeUnit());
1696                 shouldThrow();
1697             } catch (NullPointerException success) {}
1698         }
1699     }
1700 
1701     /**
1702      * timed invokeAll(,,null) throws NPE
1703      */
1704     public void testTimedInvokeAllNullTimeUnit() throws Exception {
1705         final ExecutorService e =
1706             new ThreadPoolExecutor(2, 2,
1707                                    LONG_DELAY_MS, MILLISECONDS,
1708                                    new ArrayBlockingQueue<Runnable>(10));
1709         try (PoolCleaner cleaner = cleaner(e)) {
1710             List<Callable<String>> l = new ArrayList<>();
1711             l.add(new StringTask());
1712             try {
1713                 e.invokeAll(l, randomTimeout(), null);
1714                 shouldThrow();
1715             } catch (NullPointerException success) {}
1716         }
1717     }
1718 
1719     /**
1720      * timed invokeAll(empty collection) returns empty list
1721      */
1722     public void testTimedInvokeAll2() throws InterruptedException {
1723         final ExecutorService e =
1724             new ThreadPoolExecutor(2, 2,
1725                                    LONG_DELAY_MS, MILLISECONDS,
1726                                    new ArrayBlockingQueue<Runnable>(10));
1727         final Collection<Callable<String>> emptyCollection
1728             = Collections.emptyList();
1729         try (PoolCleaner cleaner = cleaner(e)) {
1730             List<Future<String>> r =
1731                 e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit());
1732             assertTrue(r.isEmpty());
1733         }
1734     }
1735 
1736     /**
1737      * timed invokeAll(c) throws NPE if c has null elements
1738      */
1739     public void testTimedInvokeAll3() throws Exception {
1740         final ExecutorService e =
1741             new ThreadPoolExecutor(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             l.add(null);
1748             try {
1749                 e.invokeAll(l, randomTimeout(), randomTimeUnit());
1750                 shouldThrow();
1751             } catch (NullPointerException success) {}
1752         }
1753     }
1754 
1755     /**
1756      * get of element of invokeAll(c) throws exception on failed task
1757      */
1758     public void testTimedInvokeAll4() throws Exception {
1759         final ExecutorService e =
1760             new ThreadPoolExecutor(2, 2,
1761                                    LONG_DELAY_MS, MILLISECONDS,
1762                                    new ArrayBlockingQueue<Runnable>(10));
1763         try (PoolCleaner cleaner = cleaner(e)) {
1764             List<Callable<String>> l = new ArrayList<>();
1765             l.add(new NPETask());
1766             List<Future<String>> futures =
1767                 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1768             assertEquals(1, futures.size());
1769             try {
1770                 futures.get(0).get();
1771                 shouldThrow();
1772             } catch (ExecutionException success) {
1773                 assertTrue(success.getCause() instanceof NullPointerException);
1774             }
1775         }
1776     }
1777 
1778     /**
1779      * timed invokeAll(c) returns results of all completed tasks
1780      */
1781     public void testTimedInvokeAll5() throws Exception {
1782         final ExecutorService e =
1783             new ThreadPoolExecutor(2, 2,
1784                                    LONG_DELAY_MS, MILLISECONDS,
1785                                    new ArrayBlockingQueue<Runnable>(10));
1786         try (PoolCleaner cleaner = cleaner(e)) {
1787             List<Callable<String>> l = new ArrayList<>();
1788             l.add(new StringTask());
1789             l.add(new StringTask());
1790             List<Future<String>> futures =
1791                 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1792             assertEquals(2, futures.size());
1793             for (Future<String> future : futures)
1794                 assertSame(TEST_STRING, future.get());
1795         }
1796     }
1797 
1798     /**
1799      * timed invokeAll(c) cancels tasks not completed by timeout
1800      */
1801     public void testTimedInvokeAll6() throws Exception {
1802         for (long timeout = timeoutMillis();;) {
1803             final CountDownLatch done = new CountDownLatch(1);
1804             final Callable<String> waiter = new CheckedCallable<>() {
1805                 public String realCall() {
1806                     try { done.await(LONG_DELAY_MS, MILLISECONDS); }
1807                     catch (InterruptedException ok) {}
1808                     return "1"; }};
1809             final ExecutorService p =
1810                 new ThreadPoolExecutor(2, 2,
1811                                        LONG_DELAY_MS, MILLISECONDS,
1812                                        new ArrayBlockingQueue<Runnable>(10));
1813             try (PoolCleaner cleaner = cleaner(p, done)) {
1814                 List<Callable<String>> tasks = new ArrayList<>();
1815                 tasks.add(new StringTask("0"));
1816                 tasks.add(waiter);
1817                 tasks.add(new StringTask("2"));
1818                 long startTime = System.nanoTime();
1819                 List<Future<String>> futures =
1820                     p.invokeAll(tasks, timeout, MILLISECONDS);
1821                 assertEquals(tasks.size(), futures.size());
1822                 assertTrue(millisElapsedSince(startTime) >= timeout);
1823                 for (Future<?> future : futures)
1824                     assertTrue(future.isDone());
1825                 assertTrue(futures.get(1).isCancelled());
1826                 try {
1827                     assertEquals("0", futures.get(0).get());
1828                     assertEquals("2", futures.get(2).get());
1829                     break;
1830                 } catch (CancellationException retryWithLongerTimeout) {
1831                     timeout *= 2;
1832                     if (timeout >= LONG_DELAY_MS / 2)
1833                         fail("expected exactly one task to be cancelled");
1834                 }
1835             }
1836         }
1837     }
1838 
1839     /**
1840      * Execution continues if there is at least one thread even if
1841      * thread factory fails to create more
1842      */
1843     public void testFailingThreadFactory() throws InterruptedException {
1844         final ExecutorService e =
1845             new ThreadPoolExecutor(100, 100,
1846                                    LONG_DELAY_MS, MILLISECONDS,
1847                                    new LinkedBlockingQueue<Runnable>(),
1848                                    new FailingThreadFactory());
1849         try (PoolCleaner cleaner = cleaner(e)) {
1850             final int TASKS = 100;
1851             final CountDownLatch done = new CountDownLatch(TASKS);
1852             for (int k = 0; k < TASKS; ++k)
1853                 e.execute(new CheckedRunnable() {
1854                     public void realRun() {
1855                         done.countDown();
1856                     }});
1857             await(done);
1858         }
1859     }
1860 
1861     /**
1862      * allowsCoreThreadTimeOut is by default false.
1863      */
1864     public void testAllowsCoreThreadTimeOut() {
1865         final ThreadPoolExecutor p =
1866             new ThreadPoolExecutor(2, 2,
1867                                    1000, MILLISECONDS,
1868                                    new ArrayBlockingQueue<Runnable>(10));
1869         try (PoolCleaner cleaner = cleaner(p)) {
1870             assertFalse(p.allowsCoreThreadTimeOut());
1871         }
1872     }
1873 
1874     /**
1875      * allowCoreThreadTimeOut(true) causes idle threads to time out
1876      */
1877     public void testAllowCoreThreadTimeOut_true() throws Exception {
1878         long keepAliveTime = timeoutMillis();
1879         final ThreadPoolExecutor p =
1880             new ThreadPoolExecutor(2, 10,
1881                                    keepAliveTime, MILLISECONDS,
1882                                    new ArrayBlockingQueue<Runnable>(10));
1883         try (PoolCleaner cleaner = cleaner(p)) {
1884             final CountDownLatch threadStarted = new CountDownLatch(1);
1885             p.allowCoreThreadTimeOut(true);
1886             p.execute(new CheckedRunnable() {
1887                 public void realRun() {
1888                     threadStarted.countDown();
1889                     assertEquals(1, p.getPoolSize());
1890                 }});
1891             await(threadStarted);
1892             delay(keepAliveTime);
1893             long startTime = System.nanoTime();
1894             while (p.getPoolSize() > 0
1895                    && millisElapsedSince(startTime) < LONG_DELAY_MS)
1896                 Thread.yield();
1897             assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1898             assertEquals(0, p.getPoolSize());
1899         }
1900     }
1901 
1902     /**
1903      * allowCoreThreadTimeOut(false) causes idle threads not to time out
1904      */
1905     public void testAllowCoreThreadTimeOut_false() throws Exception {
1906         long keepAliveTime = timeoutMillis();
1907         final ThreadPoolExecutor p =
1908             new ThreadPoolExecutor(2, 10,
1909                                    keepAliveTime, MILLISECONDS,
1910                                    new ArrayBlockingQueue<Runnable>(10));
1911         try (PoolCleaner cleaner = cleaner(p)) {
1912             final CountDownLatch threadStarted = new CountDownLatch(1);
1913             p.allowCoreThreadTimeOut(false);
1914             p.execute(new CheckedRunnable() {
1915                 public void realRun() throws InterruptedException {
1916                     threadStarted.countDown();
1917                     assertTrue(p.getPoolSize() >= 1);
1918                 }});
1919             delay(2 * keepAliveTime);
1920             assertTrue(p.getPoolSize() >= 1);
1921         }
1922     }
1923 
1924     /**
1925      * execute allows the same task to be submitted multiple times, even
1926      * if rejected
1927      */
1928     public void testRejectedRecycledTask() throws InterruptedException {
1929         final int nTasks = 1000;
1930         final CountDownLatch done = new CountDownLatch(nTasks);
1931         final Runnable recycledTask = new Runnable() {
1932             public void run() {
1933                 done.countDown();
1934             }};
1935         final ThreadPoolExecutor p =
1936             new ThreadPoolExecutor(1, 30,
1937                                    60, SECONDS,
1938                                    new ArrayBlockingQueue<Runnable>(30));
1939         try (PoolCleaner cleaner = cleaner(p)) {
1940             for (int i = 0; i < nTasks; ++i) {
1941                 for (;;) {
1942                     try {
1943                         p.execute(recycledTask);
1944                         break;
1945                     }
1946                     catch (RejectedExecutionException ignore) {}
1947                 }
1948             }
1949             // enough time to run all tasks
1950             await(done, nTasks * SHORT_DELAY_MS);
1951         }
1952     }
1953 
1954     /**
1955      * get(cancelled task) throws CancellationException
1956      */
1957     public void testGet_cancelled() throws Exception {
1958         final CountDownLatch done = new CountDownLatch(1);
1959         final ExecutorService e =
1960             new ThreadPoolExecutor(1, 1,
1961                                    LONG_DELAY_MS, MILLISECONDS,
1962                                    new LinkedBlockingQueue<Runnable>());
1963         try (PoolCleaner cleaner = cleaner(e, done)) {
1964             final CountDownLatch blockerStarted = new CountDownLatch(1);
1965             final List<Future<?>> futures = new ArrayList<>();
1966             for (int i = 0; i < 2; i++) {
1967                 Runnable r = new CheckedRunnable() { public void realRun()
1968                                                          throws Throwable {
1969                     blockerStarted.countDown();
1970                     assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
1971                 }};
1972                 futures.add(e.submit(r));
1973             }
1974             await(blockerStarted);
1975             for (Future<?> future : futures) future.cancel(false);
1976             for (Future<?> future : futures) {
1977                 try {
1978                     future.get();
1979                     shouldThrow();
1980                 } catch (CancellationException success) {}
1981                 try {
1982                     future.get(LONG_DELAY_MS, MILLISECONDS);
1983                     shouldThrow();
1984                 } catch (CancellationException success) {}
1985                 assertTrue(future.isCancelled());
1986                 assertTrue(future.isDone());
1987             }
1988         }
1989     }
1990 
1991     /** Directly test simple ThreadPoolExecutor RejectedExecutionHandlers. */
1992     public void testStandardRejectedExecutionHandlers() {
1993         final ThreadPoolExecutor p =
1994             new ThreadPoolExecutor(1, 1, 1, SECONDS,
1995                                    new ArrayBlockingQueue<Runnable>(1));
1996         final AtomicReference<Thread> thread = new AtomicReference<>();
1997         final Runnable r = new Runnable() { public void run() {
1998             thread.set(Thread.currentThread()); }};
1999 
2000         try {
2001             new AbortPolicy().rejectedExecution(r, p);
2002             shouldThrow();
2003         } catch (RejectedExecutionException success) {}
2004         assertNull(thread.get());
2005 
2006         new DiscardPolicy().rejectedExecution(r, p);
2007         assertNull(thread.get());
2008 
2009         new CallerRunsPolicy().rejectedExecution(r, p);
2010         assertSame(Thread.currentThread(), thread.get());
2011 
2012         // check that pool was not perturbed by handlers
2013         assertTrue(p.getRejectedExecutionHandler() instanceof AbortPolicy);
2014         assertEquals(0, p.getTaskCount());
2015         assertTrue(p.getQueue().isEmpty());
2016     }
2017 
2018     public void testThreadFactoryReturnsTerminatedThread_shouldThrow() {
2019         if (!testImplementationDetails)
2020             return;
2021 
2022         ThreadFactory returnsTerminatedThread = runnableIgnored -> {
2023             Thread thread = new Thread(() -> {});
2024             thread.start();
2025             try { thread.join(); }
2026             catch (InterruptedException ex) { throw new Error(ex); }
2027             return thread;
2028         };
2029         ThreadPoolExecutor p =
2030             new ThreadPoolExecutor(1, 1, 1, SECONDS,
2031                                    new ArrayBlockingQueue<Runnable>(1),
2032                                    returnsTerminatedThread);
2033         try (PoolCleaner cleaner = cleaner(p)) {
2034             assertThrows(IllegalThreadStateException.class,
2035                          () -> p.execute(() -> {}));
2036         }
2037     }
2038 
2039     public void testThreadFactoryReturnsStartedThread_shouldThrow() {
2040         if (!testImplementationDetails)
2041             return;
2042 
2043         CountDownLatch latch = new CountDownLatch(1);
2044         Runnable awaitLatch = () -> {
2045             try { latch.await(); }
2046             catch (InterruptedException ex) { throw new Error(ex); }};
2047         ThreadFactory returnsStartedThread = runnable -> {
2048             Thread thread = new Thread(awaitLatch);
2049             thread.start();
2050             return thread;
2051         };
2052         ThreadPoolExecutor p =
2053             new ThreadPoolExecutor(1, 1, 1, SECONDS,
2054                                    new ArrayBlockingQueue<Runnable>(1),
2055                                    returnsStartedThread);
2056         try (PoolCleaner cleaner = cleaner(p)) {
2057             assertThrows(IllegalThreadStateException.class,
2058                          () -> p.execute(() -> {}));
2059             latch.countDown();
2060         }
2061     }
2062 
2063 }
2064