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