ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorTest.java
Revision: 1.61
Committed: Mon Sep 28 02:41:29 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.60: +25 -11 lines
Log Message:
improve tests for shutdownNow

File Contents

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