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