ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorTest.java
Revision: 1.116
Committed: Wed Mar 22 20:19:55 2017 UTC (7 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.115: +14 -0 lines
Log Message:
clarify default rejected execution handler and thread factory

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