ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorTest.java
Revision: 1.123
Committed: Sat Jul 15 23:15:21 2017 UTC (6 years, 10 months ago) by jsr166
Branch: MAIN
Changes since 1.122: +113 -89 lines
Log Message:
improve tests of saturated pools

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