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
9package jsr166;
10
11import static java.util.concurrent.TimeUnit.MILLISECONDS;
12import static java.util.concurrent.TimeUnit.NANOSECONDS;
13import static java.util.concurrent.TimeUnit.SECONDS;
14
15import java.util.ArrayList;
16import java.util.List;
17import java.util.concurrent.ArrayBlockingQueue;
18import java.util.concurrent.BlockingQueue;
19import java.util.concurrent.Callable;
20import java.util.concurrent.CancellationException;
21import java.util.concurrent.CountDownLatch;
22import java.util.concurrent.ExecutionException;
23import java.util.concurrent.Executors;
24import java.util.concurrent.ExecutorService;
25import java.util.concurrent.Future;
26import java.util.concurrent.FutureTask;
27import java.util.concurrent.LinkedBlockingQueue;
28import java.util.concurrent.RejectedExecutionException;
29import java.util.concurrent.RejectedExecutionHandler;
30import java.util.concurrent.SynchronousQueue;
31import java.util.concurrent.ThreadFactory;
32import java.util.concurrent.ThreadPoolExecutor;
33import java.util.concurrent.TimeUnit;
34import java.util.concurrent.atomic.AtomicInteger;
35
36import junit.framework.Test;
37import junit.framework.TestSuite;
38
39public 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
55        public ExtendedTPE() {
56            super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
57        }
58        protected void beforeExecute(Thread t, Runnable r) {
59            beforeCalled.countDown();
60        }
61        protected void afterExecute(Runnable r, Throwable t) {
62            afterCalled.countDown();
63        }
64        protected void terminated() {
65            terminatedCalled.countDown();
66        }
67
68        public boolean beforeCalled() {
69            return beforeCalled.getCount() == 0;
70        }
71        public boolean afterCalled() {
72            return afterCalled.getCount() == 0;
73        }
74        public boolean terminatedCalled() {
75            return terminatedCalled.getCount() == 0;
76        }
77    }
78
79    static class FailingThreadFactory implements ThreadFactory {
80        int calls = 0;
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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