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