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