ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorTest.java
Revision: 1.128
Committed: Wed Jan 27 01:57:24 2021 UTC (3 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.127: +6 -6 lines
Log Message:
use diamond <> pervasively

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[] rtasks = new FutureTask[5];
567 @SuppressWarnings("unchecked")
568 FutureTask<Boolean>[] tasks = (FutureTask<Boolean>[])rtasks;
569 for (int i = 0; i < tasks.length; i++) {
570 Callable<Boolean> task = new CheckedCallable<>() {
571 public Boolean realCall() throws InterruptedException {
572 threadStarted.countDown();
573 assertSame(q, p.getQueue());
574 await(done);
575 return Boolean.TRUE;
576 }};
577 tasks[i] = new FutureTask<>(task);
578 p.execute(tasks[i]);
579 }
580 await(threadStarted);
581 assertSame(q, p.getQueue());
582 assertFalse(q.contains(tasks[0]));
583 assertTrue(q.contains(tasks[tasks.length - 1]));
584 assertEquals(tasks.length - 1, q.size());
585 }
586 }
587
588 /**
589 * remove(task) removes queued task, and fails to remove active task
590 */
591 public void testRemove() throws InterruptedException {
592 final CountDownLatch done = new CountDownLatch(1);
593 BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
594 final ThreadPoolExecutor p =
595 new ThreadPoolExecutor(1, 1,
596 LONG_DELAY_MS, MILLISECONDS,
597 q);
598 try (PoolCleaner cleaner = cleaner(p, done)) {
599 Runnable[] tasks = new Runnable[6];
600 final CountDownLatch threadStarted = new CountDownLatch(1);
601 for (int i = 0; i < tasks.length; i++) {
602 tasks[i] = new CheckedRunnable() {
603 public void realRun() throws InterruptedException {
604 threadStarted.countDown();
605 await(done);
606 }};
607 p.execute(tasks[i]);
608 }
609 await(threadStarted);
610 assertFalse(p.remove(tasks[0]));
611 assertTrue(q.contains(tasks[4]));
612 assertTrue(q.contains(tasks[3]));
613 assertTrue(p.remove(tasks[4]));
614 assertFalse(p.remove(tasks[4]));
615 assertFalse(q.contains(tasks[4]));
616 assertTrue(q.contains(tasks[3]));
617 assertTrue(p.remove(tasks[3]));
618 assertFalse(q.contains(tasks[3]));
619 }
620 }
621
622 /**
623 * purge removes cancelled tasks from the queue
624 */
625 public void testPurge() throws InterruptedException {
626 final CountDownLatch threadStarted = new CountDownLatch(1);
627 final CountDownLatch done = new CountDownLatch(1);
628 final BlockingQueue<Runnable> q = new ArrayBlockingQueue<>(10);
629 final ThreadPoolExecutor p =
630 new ThreadPoolExecutor(1, 1,
631 LONG_DELAY_MS, MILLISECONDS,
632 q);
633 try (PoolCleaner cleaner = cleaner(p, done)) {
634 FutureTask[] rtasks = new FutureTask[5];
635 @SuppressWarnings("unchecked")
636 FutureTask<Boolean>[] tasks = (FutureTask<Boolean>[])rtasks;
637 for (int i = 0; i < tasks.length; i++) {
638 Callable<Boolean> task = new CheckedCallable<>() {
639 public Boolean realCall() throws InterruptedException {
640 threadStarted.countDown();
641 await(done);
642 return Boolean.TRUE;
643 }};
644 tasks[i] = new FutureTask<>(task);
645 p.execute(tasks[i]);
646 }
647 await(threadStarted);
648 assertEquals(tasks.length, p.getTaskCount());
649 assertEquals(tasks.length - 1, q.size());
650 assertEquals(1L, p.getActiveCount());
651 assertEquals(0L, p.getCompletedTaskCount());
652 tasks[4].cancel(true);
653 tasks[3].cancel(false);
654 p.purge();
655 assertEquals(tasks.length - 3, q.size());
656 assertEquals(tasks.length - 2, p.getTaskCount());
657 p.purge(); // Nothing to do
658 assertEquals(tasks.length - 3, q.size());
659 assertEquals(tasks.length - 2, p.getTaskCount());
660 }
661 }
662
663 /**
664 * shutdownNow returns a list containing tasks that were not run,
665 * and those tasks are drained from the queue
666 */
667 public void testShutdownNow() throws InterruptedException {
668 final int poolSize = 2;
669 final int count = 5;
670 final AtomicInteger ran = new AtomicInteger(0);
671 final ThreadPoolExecutor p =
672 new ThreadPoolExecutor(poolSize, poolSize,
673 LONG_DELAY_MS, MILLISECONDS,
674 new ArrayBlockingQueue<Runnable>(10));
675 final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
676 Runnable waiter = new CheckedRunnable() { public void realRun() {
677 threadsStarted.countDown();
678 try {
679 MILLISECONDS.sleep(LONGER_DELAY_MS);
680 } catch (InterruptedException success) {}
681 ran.getAndIncrement();
682 }};
683 for (int i = 0; i < count; i++)
684 p.execute(waiter);
685 await(threadsStarted);
686 assertEquals(poolSize, p.getActiveCount());
687 assertEquals(0, p.getCompletedTaskCount());
688 final List<Runnable> queuedTasks;
689 try {
690 queuedTasks = p.shutdownNow();
691 } catch (SecurityException ok) {
692 return; // Allowed in case test doesn't have privs
693 }
694 assertTrue(p.isShutdown());
695 assertTrue(p.getQueue().isEmpty());
696 assertEquals(count - poolSize, queuedTasks.size());
697 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
698 assertTrue(p.isTerminated());
699 assertEquals(poolSize, ran.get());
700 assertEquals(poolSize, p.getCompletedTaskCount());
701 }
702
703 // Exception Tests
704
705 /**
706 * Constructor throws if corePoolSize argument is less than zero
707 */
708 public void testConstructor1() {
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 less than zero
718 */
719 public void testConstructor2() {
720 try {
721 new ThreadPoolExecutor(1, -1, 1L, SECONDS,
722 new ArrayBlockingQueue<Runnable>(10));
723 shouldThrow();
724 } catch (IllegalArgumentException success) {}
725 }
726
727 /**
728 * Constructor throws if maximumPoolSize is equal to zero
729 */
730 public void testConstructor3() {
731 try {
732 new ThreadPoolExecutor(1, 0, 1L, SECONDS,
733 new ArrayBlockingQueue<Runnable>(10));
734 shouldThrow();
735 } catch (IllegalArgumentException success) {}
736 }
737
738 /**
739 * Constructor throws if keepAliveTime is less than zero
740 */
741 public void testConstructor4() {
742 try {
743 new ThreadPoolExecutor(1, 2, -1L, SECONDS,
744 new ArrayBlockingQueue<Runnable>(10));
745 shouldThrow();
746 } catch (IllegalArgumentException success) {}
747 }
748
749 /**
750 * Constructor throws if corePoolSize is greater than the maximumPoolSize
751 */
752 public void testConstructor5() {
753 try {
754 new ThreadPoolExecutor(2, 1, 1L, SECONDS,
755 new ArrayBlockingQueue<Runnable>(10));
756 shouldThrow();
757 } catch (IllegalArgumentException success) {}
758 }
759
760 /**
761 * Constructor throws if workQueue is set to null
762 */
763 public void testConstructorNullPointerException() {
764 try {
765 new ThreadPoolExecutor(1, 2, 1L, SECONDS,
766 (BlockingQueue<Runnable>) null);
767 shouldThrow();
768 } catch (NullPointerException success) {}
769 }
770
771 /**
772 * Constructor throws if corePoolSize argument is less than zero
773 */
774 public void testConstructor6() {
775 try {
776 new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
777 new ArrayBlockingQueue<Runnable>(10),
778 new SimpleThreadFactory());
779 shouldThrow();
780 } catch (IllegalArgumentException success) {}
781 }
782
783 /**
784 * Constructor throws if maximumPoolSize is less than zero
785 */
786 public void testConstructor7() {
787 try {
788 new ThreadPoolExecutor(1, -1, 1L, SECONDS,
789 new ArrayBlockingQueue<Runnable>(10),
790 new SimpleThreadFactory());
791 shouldThrow();
792 } catch (IllegalArgumentException success) {}
793 }
794
795 /**
796 * Constructor throws if maximumPoolSize is equal to zero
797 */
798 public void testConstructor8() {
799 try {
800 new ThreadPoolExecutor(1, 0, 1L, SECONDS,
801 new ArrayBlockingQueue<Runnable>(10),
802 new SimpleThreadFactory());
803 shouldThrow();
804 } catch (IllegalArgumentException success) {}
805 }
806
807 /**
808 * Constructor throws if keepAliveTime is less than zero
809 */
810 public void testConstructor9() {
811 try {
812 new ThreadPoolExecutor(1, 2, -1L, SECONDS,
813 new ArrayBlockingQueue<Runnable>(10),
814 new SimpleThreadFactory());
815 shouldThrow();
816 } catch (IllegalArgumentException success) {}
817 }
818
819 /**
820 * Constructor throws if corePoolSize is greater than the maximumPoolSize
821 */
822 public void testConstructor10() {
823 try {
824 new ThreadPoolExecutor(2, 1, 1L, SECONDS,
825 new ArrayBlockingQueue<Runnable>(10),
826 new SimpleThreadFactory());
827 shouldThrow();
828 } catch (IllegalArgumentException success) {}
829 }
830
831 /**
832 * Constructor throws if workQueue is set to null
833 */
834 public void testConstructorNullPointerException2() {
835 try {
836 new ThreadPoolExecutor(1, 2, 1L, SECONDS,
837 (BlockingQueue<Runnable>) null,
838 new SimpleThreadFactory());
839 shouldThrow();
840 } catch (NullPointerException success) {}
841 }
842
843 /**
844 * Constructor throws if threadFactory is set to null
845 */
846 public void testConstructorNullPointerException3() {
847 try {
848 new ThreadPoolExecutor(1, 2, 1L, SECONDS,
849 new ArrayBlockingQueue<Runnable>(10),
850 (ThreadFactory) null);
851 shouldThrow();
852 } catch (NullPointerException success) {}
853 }
854
855 /**
856 * Constructor throws if corePoolSize argument is less than zero
857 */
858 public void testConstructor11() {
859 try {
860 new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
861 new ArrayBlockingQueue<Runnable>(10),
862 new NoOpREHandler());
863 shouldThrow();
864 } catch (IllegalArgumentException success) {}
865 }
866
867 /**
868 * Constructor throws if maximumPoolSize is less than zero
869 */
870 public void testConstructor12() {
871 try {
872 new ThreadPoolExecutor(1, -1, 1L, SECONDS,
873 new ArrayBlockingQueue<Runnable>(10),
874 new NoOpREHandler());
875 shouldThrow();
876 } catch (IllegalArgumentException success) {}
877 }
878
879 /**
880 * Constructor throws if maximumPoolSize is equal to zero
881 */
882 public void testConstructor13() {
883 try {
884 new ThreadPoolExecutor(1, 0, 1L, SECONDS,
885 new ArrayBlockingQueue<Runnable>(10),
886 new NoOpREHandler());
887 shouldThrow();
888 } catch (IllegalArgumentException success) {}
889 }
890
891 /**
892 * Constructor throws if keepAliveTime is less than zero
893 */
894 public void testConstructor14() {
895 try {
896 new ThreadPoolExecutor(1, 2, -1L, SECONDS,
897 new ArrayBlockingQueue<Runnable>(10),
898 new NoOpREHandler());
899 shouldThrow();
900 } catch (IllegalArgumentException success) {}
901 }
902
903 /**
904 * Constructor throws if corePoolSize is greater than the maximumPoolSize
905 */
906 public void testConstructor15() {
907 try {
908 new ThreadPoolExecutor(2, 1, 1L, SECONDS,
909 new ArrayBlockingQueue<Runnable>(10),
910 new NoOpREHandler());
911 shouldThrow();
912 } catch (IllegalArgumentException success) {}
913 }
914
915 /**
916 * Constructor throws if workQueue is set to null
917 */
918 public void testConstructorNullPointerException4() {
919 try {
920 new ThreadPoolExecutor(1, 2, 1L, SECONDS,
921 (BlockingQueue<Runnable>) null,
922 new NoOpREHandler());
923 shouldThrow();
924 } catch (NullPointerException success) {}
925 }
926
927 /**
928 * Constructor throws if handler is set to null
929 */
930 public void testConstructorNullPointerException5() {
931 try {
932 new ThreadPoolExecutor(1, 2, 1L, SECONDS,
933 new ArrayBlockingQueue<Runnable>(10),
934 (RejectedExecutionHandler) null);
935 shouldThrow();
936 } catch (NullPointerException success) {}
937 }
938
939 /**
940 * Constructor throws if corePoolSize argument is less than zero
941 */
942 public void testConstructor16() {
943 try {
944 new ThreadPoolExecutor(-1, 1, 1L, SECONDS,
945 new ArrayBlockingQueue<Runnable>(10),
946 new SimpleThreadFactory(),
947 new NoOpREHandler());
948 shouldThrow();
949 } catch (IllegalArgumentException success) {}
950 }
951
952 /**
953 * Constructor throws if maximumPoolSize is less than zero
954 */
955 public void testConstructor17() {
956 try {
957 new ThreadPoolExecutor(1, -1, 1L, SECONDS,
958 new ArrayBlockingQueue<Runnable>(10),
959 new SimpleThreadFactory(),
960 new NoOpREHandler());
961 shouldThrow();
962 } catch (IllegalArgumentException success) {}
963 }
964
965 /**
966 * Constructor throws if maximumPoolSize is equal to zero
967 */
968 public void testConstructor18() {
969 try {
970 new ThreadPoolExecutor(1, 0, 1L, SECONDS,
971 new ArrayBlockingQueue<Runnable>(10),
972 new SimpleThreadFactory(),
973 new NoOpREHandler());
974 shouldThrow();
975 } catch (IllegalArgumentException success) {}
976 }
977
978 /**
979 * Constructor throws if keepAliveTime is less than zero
980 */
981 public void testConstructor19() {
982 try {
983 new ThreadPoolExecutor(1, 2, -1L, SECONDS,
984 new ArrayBlockingQueue<Runnable>(10),
985 new SimpleThreadFactory(),
986 new NoOpREHandler());
987 shouldThrow();
988 } catch (IllegalArgumentException success) {}
989 }
990
991 /**
992 * Constructor throws if corePoolSize is greater than the maximumPoolSize
993 */
994 public void testConstructor20() {
995 try {
996 new ThreadPoolExecutor(2, 1, 1L, SECONDS,
997 new ArrayBlockingQueue<Runnable>(10),
998 new SimpleThreadFactory(),
999 new NoOpREHandler());
1000 shouldThrow();
1001 } catch (IllegalArgumentException success) {}
1002 }
1003
1004 /**
1005 * Constructor throws if workQueue is null
1006 */
1007 public void testConstructorNullPointerException6() {
1008 try {
1009 new ThreadPoolExecutor(1, 2, 1L, SECONDS,
1010 (BlockingQueue<Runnable>) null,
1011 new SimpleThreadFactory(),
1012 new NoOpREHandler());
1013 shouldThrow();
1014 } catch (NullPointerException success) {}
1015 }
1016
1017 /**
1018 * Constructor throws if handler is null
1019 */
1020 public void testConstructorNullPointerException7() {
1021 try {
1022 new ThreadPoolExecutor(1, 2, 1L, SECONDS,
1023 new ArrayBlockingQueue<Runnable>(10),
1024 new SimpleThreadFactory(),
1025 (RejectedExecutionHandler) null);
1026 shouldThrow();
1027 } catch (NullPointerException success) {}
1028 }
1029
1030 /**
1031 * Constructor throws if ThreadFactory is null
1032 */
1033 public void testConstructorNullPointerException8() {
1034 try {
1035 new ThreadPoolExecutor(1, 2, 1L, SECONDS,
1036 new ArrayBlockingQueue<Runnable>(10),
1037 (ThreadFactory) null,
1038 new NoOpREHandler());
1039 shouldThrow();
1040 } catch (NullPointerException success) {}
1041 }
1042
1043 /**
1044 * get of submitted callable throws InterruptedException if interrupted
1045 */
1046 public void testInterruptedSubmit() throws InterruptedException {
1047 final CountDownLatch done = new CountDownLatch(1);
1048 final ThreadPoolExecutor p =
1049 new ThreadPoolExecutor(1, 1,
1050 60, SECONDS,
1051 new ArrayBlockingQueue<Runnable>(10));
1052
1053 try (PoolCleaner cleaner = cleaner(p, done)) {
1054 final CountDownLatch threadStarted = new CountDownLatch(1);
1055 Thread t = newStartedThread(new CheckedInterruptedRunnable() {
1056 public void realRun() throws Exception {
1057 Callable<Boolean> task = new CheckedCallable<>() {
1058 public Boolean realCall() throws InterruptedException {
1059 threadStarted.countDown();
1060 await(done);
1061 return Boolean.TRUE;
1062 }};
1063 p.submit(task).get();
1064 }});
1065
1066 await(threadStarted); // ensure quiescence
1067 t.interrupt();
1068 awaitTermination(t);
1069 }
1070 }
1071
1072 /**
1073 * Submitted tasks are rejected when saturated or shutdown
1074 */
1075 public void testSubmittedTasksRejectedWhenSaturatedOrShutdown() throws InterruptedException {
1076 final ThreadPoolExecutor p = new ThreadPoolExecutor(
1077 1, 1, 1, SECONDS, new ArrayBlockingQueue<Runnable>(1));
1078 final int saturatedSize = saturatedSize(p);
1079 final ThreadLocalRandom rnd = ThreadLocalRandom.current();
1080 final CountDownLatch threadsStarted = new CountDownLatch(p.getMaximumPoolSize());
1081 final CountDownLatch done = new CountDownLatch(1);
1082 final Runnable r = () -> {
1083 threadsStarted.countDown();
1084 for (;;) {
1085 try {
1086 done.await();
1087 return;
1088 } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
1089 }};
1090 final Callable<Boolean> c = () -> {
1091 threadsStarted.countDown();
1092 for (;;) {
1093 try {
1094 done.await();
1095 return Boolean.TRUE;
1096 } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
1097 }};
1098 final boolean shutdownNow = rnd.nextBoolean();
1099
1100 try (PoolCleaner cleaner = cleaner(p, done)) {
1101 // saturate
1102 for (int i = saturatedSize; i--> 0; ) {
1103 switch (rnd.nextInt(4)) {
1104 case 0: p.execute(r); break;
1105 case 1: assertFalse(p.submit(r).isDone()); break;
1106 case 2: assertFalse(p.submit(r, Boolean.TRUE).isDone()); break;
1107 case 3: assertFalse(p.submit(c).isDone()); break;
1108 }
1109 }
1110
1111 await(threadsStarted);
1112 assertTaskSubmissionsAreRejected(p);
1113
1114 if (shutdownNow)
1115 p.shutdownNow();
1116 else
1117 p.shutdown();
1118 // Pool is shutdown, but not yet terminated
1119 assertTaskSubmissionsAreRejected(p);
1120 assertFalse(p.isTerminated());
1121
1122 done.countDown(); // release blocking tasks
1123 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
1124
1125 assertTaskSubmissionsAreRejected(p);
1126 }
1127 assertEquals(saturatedSize(p)
1128 - (shutdownNow ? p.getQueue().remainingCapacity() : 0),
1129 p.getCompletedTaskCount());
1130 }
1131
1132 /**
1133 * executor using DiscardOldestPolicy drops oldest task if saturated.
1134 */
1135 public void testSaturatedExecute_DiscardOldestPolicy() {
1136 final CountDownLatch done = new CountDownLatch(1);
1137 LatchAwaiter r1 = awaiter(done);
1138 LatchAwaiter r2 = awaiter(done);
1139 LatchAwaiter r3 = awaiter(done);
1140 final ThreadPoolExecutor p =
1141 new ThreadPoolExecutor(1, 1,
1142 LONG_DELAY_MS, MILLISECONDS,
1143 new ArrayBlockingQueue<Runnable>(1),
1144 new DiscardOldestPolicy());
1145 try (PoolCleaner cleaner = cleaner(p, done)) {
1146 assertEquals(LatchAwaiter.NEW, r1.state);
1147 assertEquals(LatchAwaiter.NEW, r2.state);
1148 assertEquals(LatchAwaiter.NEW, r3.state);
1149 p.execute(r1);
1150 p.execute(r2);
1151 assertTrue(p.getQueue().contains(r2));
1152 p.execute(r3);
1153 assertFalse(p.getQueue().contains(r2));
1154 assertTrue(p.getQueue().contains(r3));
1155 }
1156 assertEquals(LatchAwaiter.DONE, r1.state);
1157 assertEquals(LatchAwaiter.NEW, r2.state);
1158 assertEquals(LatchAwaiter.DONE, r3.state);
1159 }
1160
1161 /**
1162 * execute using DiscardOldestPolicy drops task on shutdown
1163 */
1164 public void testDiscardOldestOnShutdown() {
1165 final ThreadPoolExecutor p =
1166 new ThreadPoolExecutor(1, 1,
1167 LONG_DELAY_MS, MILLISECONDS,
1168 new ArrayBlockingQueue<Runnable>(1),
1169 new DiscardOldestPolicy());
1170
1171 try { p.shutdown(); } catch (SecurityException ok) { return; }
1172 try (PoolCleaner cleaner = cleaner(p)) {
1173 TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1174 p.execute(r);
1175 assertFalse(r.done);
1176 }
1177 }
1178
1179 /**
1180 * Submitting null tasks throws NullPointerException
1181 */
1182 public void testNullTaskSubmission() {
1183 final ThreadPoolExecutor p =
1184 new ThreadPoolExecutor(1, 2,
1185 1L, SECONDS,
1186 new ArrayBlockingQueue<Runnable>(10));
1187 try (PoolCleaner cleaner = cleaner(p)) {
1188 assertNullTaskSubmissionThrowsNullPointerException(p);
1189 }
1190 }
1191
1192 /**
1193 * setCorePoolSize of negative value throws IllegalArgumentException
1194 */
1195 public void testCorePoolSizeIllegalArgumentException() {
1196 final ThreadPoolExecutor p =
1197 new ThreadPoolExecutor(1, 2,
1198 LONG_DELAY_MS, MILLISECONDS,
1199 new ArrayBlockingQueue<Runnable>(10));
1200 try (PoolCleaner cleaner = cleaner(p)) {
1201 try {
1202 p.setCorePoolSize(-1);
1203 shouldThrow();
1204 } catch (IllegalArgumentException success) {}
1205 }
1206 }
1207
1208 /**
1209 * setMaximumPoolSize(int) throws IllegalArgumentException if
1210 * given a value less the core pool size
1211 */
1212 public void testMaximumPoolSizeIllegalArgumentException() {
1213 final ThreadPoolExecutor p =
1214 new ThreadPoolExecutor(2, 3,
1215 LONG_DELAY_MS, MILLISECONDS,
1216 new ArrayBlockingQueue<Runnable>(10));
1217 try (PoolCleaner cleaner = cleaner(p)) {
1218 try {
1219 p.setMaximumPoolSize(1);
1220 shouldThrow();
1221 } catch (IllegalArgumentException success) {}
1222 }
1223 }
1224
1225 /**
1226 * setMaximumPoolSize throws IllegalArgumentException
1227 * if given a negative value
1228 */
1229 public void testMaximumPoolSizeIllegalArgumentException2() {
1230 final ThreadPoolExecutor p =
1231 new ThreadPoolExecutor(2, 3,
1232 LONG_DELAY_MS, MILLISECONDS,
1233 new ArrayBlockingQueue<Runnable>(10));
1234 try (PoolCleaner cleaner = cleaner(p)) {
1235 try {
1236 p.setMaximumPoolSize(-1);
1237 shouldThrow();
1238 } catch (IllegalArgumentException success) {}
1239 }
1240 }
1241
1242 /**
1243 * Configuration changes that allow core pool size greater than
1244 * max pool size result in IllegalArgumentException.
1245 */
1246 public void testPoolSizeInvariants() {
1247 final ThreadPoolExecutor p =
1248 new ThreadPoolExecutor(1, 1,
1249 LONG_DELAY_MS, MILLISECONDS,
1250 new ArrayBlockingQueue<Runnable>(10));
1251 try (PoolCleaner cleaner = cleaner(p)) {
1252 for (int s = 1; s < 5; s++) {
1253 p.setMaximumPoolSize(s);
1254 p.setCorePoolSize(s);
1255 try {
1256 p.setMaximumPoolSize(s - 1);
1257 shouldThrow();
1258 } catch (IllegalArgumentException success) {}
1259 assertEquals(s, p.getCorePoolSize());
1260 assertEquals(s, p.getMaximumPoolSize());
1261 try {
1262 p.setCorePoolSize(s + 1);
1263 shouldThrow();
1264 } catch (IllegalArgumentException success) {}
1265 assertEquals(s, p.getCorePoolSize());
1266 assertEquals(s, p.getMaximumPoolSize());
1267 }
1268 }
1269 }
1270
1271 /**
1272 * setKeepAliveTime throws IllegalArgumentException
1273 * when given a negative value
1274 */
1275 public void testKeepAliveTimeIllegalArgumentException() {
1276 final ThreadPoolExecutor p =
1277 new ThreadPoolExecutor(2, 3,
1278 LONG_DELAY_MS, MILLISECONDS,
1279 new ArrayBlockingQueue<Runnable>(10));
1280 try (PoolCleaner cleaner = cleaner(p)) {
1281 try {
1282 p.setKeepAliveTime(-1, MILLISECONDS);
1283 shouldThrow();
1284 } catch (IllegalArgumentException success) {}
1285 }
1286 }
1287
1288 /**
1289 * terminated() is called on termination
1290 */
1291 public void testTerminated() {
1292 ExtendedTPE p = new ExtendedTPE();
1293 try (PoolCleaner cleaner = cleaner(p)) {
1294 try { p.shutdown(); } catch (SecurityException ok) { return; }
1295 assertTrue(p.terminatedCalled());
1296 assertTrue(p.isShutdown());
1297 }
1298 }
1299
1300 /**
1301 * beforeExecute and afterExecute are called when executing task
1302 */
1303 public void testBeforeAfter() throws InterruptedException {
1304 ExtendedTPE p = new ExtendedTPE();
1305 try (PoolCleaner cleaner = cleaner(p)) {
1306 final CountDownLatch done = new CountDownLatch(1);
1307 p.execute(new CheckedRunnable() {
1308 public void realRun() {
1309 done.countDown();
1310 }});
1311 await(p.afterCalled);
1312 assertEquals(0, done.getCount());
1313 assertTrue(p.afterCalled());
1314 assertTrue(p.beforeCalled());
1315 }
1316 }
1317
1318 /**
1319 * completed submit of callable returns result
1320 */
1321 public void testSubmitCallable() throws Exception {
1322 final ExecutorService e =
1323 new ThreadPoolExecutor(2, 2,
1324 LONG_DELAY_MS, MILLISECONDS,
1325 new ArrayBlockingQueue<Runnable>(10));
1326 try (PoolCleaner cleaner = cleaner(e)) {
1327 Future<String> future = e.submit(new StringTask());
1328 String result = future.get();
1329 assertSame(TEST_STRING, result);
1330 }
1331 }
1332
1333 /**
1334 * completed submit of runnable returns successfully
1335 */
1336 public void testSubmitRunnable() throws Exception {
1337 final ExecutorService e =
1338 new ThreadPoolExecutor(2, 2,
1339 LONG_DELAY_MS, MILLISECONDS,
1340 new ArrayBlockingQueue<Runnable>(10));
1341 try (PoolCleaner cleaner = cleaner(e)) {
1342 Future<?> future = e.submit(new NoOpRunnable());
1343 future.get();
1344 assertTrue(future.isDone());
1345 }
1346 }
1347
1348 /**
1349 * completed submit of (runnable, result) returns result
1350 */
1351 public void testSubmitRunnable2() throws Exception {
1352 final ExecutorService e =
1353 new ThreadPoolExecutor(2, 2,
1354 LONG_DELAY_MS, MILLISECONDS,
1355 new ArrayBlockingQueue<Runnable>(10));
1356 try (PoolCleaner cleaner = cleaner(e)) {
1357 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
1358 String result = future.get();
1359 assertSame(TEST_STRING, result);
1360 }
1361 }
1362
1363 /**
1364 * invokeAny(null) throws NPE
1365 */
1366 public void testInvokeAny1() throws Exception {
1367 final ExecutorService e =
1368 new ThreadPoolExecutor(2, 2,
1369 LONG_DELAY_MS, MILLISECONDS,
1370 new ArrayBlockingQueue<Runnable>(10));
1371 try (PoolCleaner cleaner = cleaner(e)) {
1372 try {
1373 e.invokeAny(null);
1374 shouldThrow();
1375 } catch (NullPointerException success) {}
1376 }
1377 }
1378
1379 /**
1380 * invokeAny(empty collection) throws IllegalArgumentException
1381 */
1382 public void testInvokeAny2() throws Exception {
1383 final ExecutorService e =
1384 new ThreadPoolExecutor(2, 2,
1385 LONG_DELAY_MS, MILLISECONDS,
1386 new ArrayBlockingQueue<Runnable>(10));
1387 try (PoolCleaner cleaner = cleaner(e)) {
1388 try {
1389 e.invokeAny(new ArrayList<Callable<String>>());
1390 shouldThrow();
1391 } catch (IllegalArgumentException success) {}
1392 }
1393 }
1394
1395 /**
1396 * invokeAny(c) throws NPE if c has null elements
1397 */
1398 public void testInvokeAny3() throws Exception {
1399 final CountDownLatch latch = new CountDownLatch(1);
1400 final ExecutorService e =
1401 new ThreadPoolExecutor(2, 2,
1402 LONG_DELAY_MS, MILLISECONDS,
1403 new ArrayBlockingQueue<Runnable>(10));
1404 try (PoolCleaner cleaner = cleaner(e)) {
1405 List<Callable<String>> l = new ArrayList<>();
1406 l.add(latchAwaitingStringTask(latch));
1407 l.add(null);
1408 try {
1409 e.invokeAny(l);
1410 shouldThrow();
1411 } catch (NullPointerException success) {}
1412 latch.countDown();
1413 }
1414 }
1415
1416 /**
1417 * invokeAny(c) throws ExecutionException if no task completes
1418 */
1419 public void testInvokeAny4() throws Exception {
1420 final ExecutorService e =
1421 new ThreadPoolExecutor(2, 2,
1422 LONG_DELAY_MS, MILLISECONDS,
1423 new ArrayBlockingQueue<Runnable>(10));
1424 try (PoolCleaner cleaner = cleaner(e)) {
1425 List<Callable<String>> l = new ArrayList<>();
1426 l.add(new NPETask());
1427 try {
1428 e.invokeAny(l);
1429 shouldThrow();
1430 } catch (ExecutionException success) {
1431 assertTrue(success.getCause() instanceof NullPointerException);
1432 }
1433 }
1434 }
1435
1436 /**
1437 * invokeAny(c) returns result of some task
1438 */
1439 public void testInvokeAny5() 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 List<Callable<String>> l = new ArrayList<>();
1446 l.add(new StringTask());
1447 l.add(new StringTask());
1448 String result = e.invokeAny(l);
1449 assertSame(TEST_STRING, result);
1450 }
1451 }
1452
1453 /**
1454 * invokeAll(null) throws NPE
1455 */
1456 public void testInvokeAll1() throws Exception {
1457 final ExecutorService e =
1458 new ThreadPoolExecutor(2, 2,
1459 LONG_DELAY_MS, MILLISECONDS,
1460 new ArrayBlockingQueue<Runnable>(10));
1461 try (PoolCleaner cleaner = cleaner(e)) {
1462 try {
1463 e.invokeAll(null);
1464 shouldThrow();
1465 } catch (NullPointerException success) {}
1466 }
1467 }
1468
1469 /**
1470 * invokeAll(empty collection) returns empty list
1471 */
1472 public void testInvokeAll2() throws InterruptedException {
1473 final ExecutorService e =
1474 new ThreadPoolExecutor(2, 2,
1475 LONG_DELAY_MS, MILLISECONDS,
1476 new ArrayBlockingQueue<Runnable>(10));
1477 final Collection<Callable<String>> emptyCollection
1478 = Collections.emptyList();
1479 try (PoolCleaner cleaner = cleaner(e)) {
1480 List<Future<String>> r = e.invokeAll(emptyCollection);
1481 assertTrue(r.isEmpty());
1482 }
1483 }
1484
1485 /**
1486 * invokeAll(c) throws NPE if c has null elements
1487 */
1488 public void testInvokeAll3() throws Exception {
1489 final ExecutorService e =
1490 new ThreadPoolExecutor(2, 2,
1491 LONG_DELAY_MS, MILLISECONDS,
1492 new ArrayBlockingQueue<Runnable>(10));
1493 try (PoolCleaner cleaner = cleaner(e)) {
1494 List<Callable<String>> l = new ArrayList<>();
1495 l.add(new StringTask());
1496 l.add(null);
1497 try {
1498 e.invokeAll(l);
1499 shouldThrow();
1500 } catch (NullPointerException success) {}
1501 }
1502 }
1503
1504 /**
1505 * get of element of invokeAll(c) throws exception on failed task
1506 */
1507 public void testInvokeAll4() throws Exception {
1508 final ExecutorService e =
1509 new ThreadPoolExecutor(2, 2,
1510 LONG_DELAY_MS, MILLISECONDS,
1511 new ArrayBlockingQueue<Runnable>(10));
1512 try (PoolCleaner cleaner = cleaner(e)) {
1513 List<Callable<String>> l = new ArrayList<>();
1514 l.add(new NPETask());
1515 List<Future<String>> futures = e.invokeAll(l);
1516 assertEquals(1, futures.size());
1517 try {
1518 futures.get(0).get();
1519 shouldThrow();
1520 } catch (ExecutionException success) {
1521 assertTrue(success.getCause() instanceof NullPointerException);
1522 }
1523 }
1524 }
1525
1526 /**
1527 * invokeAll(c) returns results of all completed tasks
1528 */
1529 public void testInvokeAll5() throws Exception {
1530 final ExecutorService e =
1531 new ThreadPoolExecutor(2, 2,
1532 LONG_DELAY_MS, MILLISECONDS,
1533 new ArrayBlockingQueue<Runnable>(10));
1534 try (PoolCleaner cleaner = cleaner(e)) {
1535 List<Callable<String>> l = new ArrayList<>();
1536 l.add(new StringTask());
1537 l.add(new StringTask());
1538 List<Future<String>> futures = e.invokeAll(l);
1539 assertEquals(2, futures.size());
1540 for (Future<String> future : futures)
1541 assertSame(TEST_STRING, future.get());
1542 }
1543 }
1544
1545 /**
1546 * timed invokeAny(null) throws NPE
1547 */
1548 public void testTimedInvokeAny1() throws Exception {
1549 final ExecutorService e =
1550 new ThreadPoolExecutor(2, 2,
1551 LONG_DELAY_MS, MILLISECONDS,
1552 new ArrayBlockingQueue<Runnable>(10));
1553 try (PoolCleaner cleaner = cleaner(e)) {
1554 try {
1555 e.invokeAny(null, randomTimeout(), randomTimeUnit());
1556 shouldThrow();
1557 } catch (NullPointerException success) {}
1558 }
1559 }
1560
1561 /**
1562 * timed invokeAny(,,null) throws NPE
1563 */
1564 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
1565 final ExecutorService e =
1566 new ThreadPoolExecutor(2, 2,
1567 LONG_DELAY_MS, MILLISECONDS,
1568 new ArrayBlockingQueue<Runnable>(10));
1569 try (PoolCleaner cleaner = cleaner(e)) {
1570 List<Callable<String>> l = new ArrayList<>();
1571 l.add(new StringTask());
1572 try {
1573 e.invokeAny(l, randomTimeout(), null);
1574 shouldThrow();
1575 } catch (NullPointerException success) {}
1576 }
1577 }
1578
1579 /**
1580 * timed invokeAny(empty collection) throws IllegalArgumentException
1581 */
1582 public void testTimedInvokeAny2() throws Exception {
1583 final ExecutorService e =
1584 new ThreadPoolExecutor(2, 2,
1585 LONG_DELAY_MS, MILLISECONDS,
1586 new ArrayBlockingQueue<Runnable>(10));
1587 try (PoolCleaner cleaner = cleaner(e)) {
1588 try {
1589 e.invokeAny(new ArrayList<Callable<String>>(),
1590 randomTimeout(), randomTimeUnit());
1591 shouldThrow();
1592 } catch (IllegalArgumentException success) {}
1593 }
1594 }
1595
1596 /**
1597 * timed invokeAny(c) throws NullPointerException if c has null elements
1598 */
1599 public void testTimedInvokeAny3() throws Exception {
1600 final CountDownLatch latch = new CountDownLatch(1);
1601 final ExecutorService e =
1602 new ThreadPoolExecutor(2, 2,
1603 LONG_DELAY_MS, MILLISECONDS,
1604 new ArrayBlockingQueue<Runnable>(10));
1605 try (PoolCleaner cleaner = cleaner(e)) {
1606 List<Callable<String>> l = new ArrayList<>();
1607 l.add(latchAwaitingStringTask(latch));
1608 l.add(null);
1609 try {
1610 e.invokeAny(l, randomTimeout(), randomTimeUnit());
1611 shouldThrow();
1612 } catch (NullPointerException success) {}
1613 latch.countDown();
1614 }
1615 }
1616
1617 /**
1618 * timed invokeAny(c) throws ExecutionException if no task completes
1619 */
1620 public void testTimedInvokeAny4() throws Exception {
1621 final ExecutorService e =
1622 new ThreadPoolExecutor(2, 2,
1623 LONG_DELAY_MS, MILLISECONDS,
1624 new ArrayBlockingQueue<Runnable>(10));
1625 try (PoolCleaner cleaner = cleaner(e)) {
1626 long startTime = System.nanoTime();
1627 List<Callable<String>> l = new ArrayList<>();
1628 l.add(new NPETask());
1629 try {
1630 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1631 shouldThrow();
1632 } catch (ExecutionException success) {
1633 assertTrue(success.getCause() instanceof NullPointerException);
1634 }
1635 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1636 }
1637 }
1638
1639 /**
1640 * timed invokeAny(c) returns result of some task
1641 */
1642 public void testTimedInvokeAny5() throws Exception {
1643 final ExecutorService e =
1644 new ThreadPoolExecutor(2, 2,
1645 LONG_DELAY_MS, MILLISECONDS,
1646 new ArrayBlockingQueue<Runnable>(10));
1647 try (PoolCleaner cleaner = cleaner(e)) {
1648 long startTime = System.nanoTime();
1649 List<Callable<String>> l = new ArrayList<>();
1650 l.add(new StringTask());
1651 l.add(new StringTask());
1652 String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1653 assertSame(TEST_STRING, result);
1654 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1655 }
1656 }
1657
1658 /**
1659 * timed invokeAll(null) throws NPE
1660 */
1661 public void testTimedInvokeAll1() throws Exception {
1662 final ExecutorService e =
1663 new ThreadPoolExecutor(2, 2,
1664 LONG_DELAY_MS, MILLISECONDS,
1665 new ArrayBlockingQueue<Runnable>(10));
1666 try (PoolCleaner cleaner = cleaner(e)) {
1667 try {
1668 e.invokeAll(null, randomTimeout(), randomTimeUnit());
1669 shouldThrow();
1670 } catch (NullPointerException success) {}
1671 }
1672 }
1673
1674 /**
1675 * timed invokeAll(,,null) throws NPE
1676 */
1677 public void testTimedInvokeAllNullTimeUnit() 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 try {
1686 e.invokeAll(l, randomTimeout(), null);
1687 shouldThrow();
1688 } catch (NullPointerException success) {}
1689 }
1690 }
1691
1692 /**
1693 * timed invokeAll(empty collection) returns empty list
1694 */
1695 public void testTimedInvokeAll2() throws InterruptedException {
1696 final ExecutorService e =
1697 new ThreadPoolExecutor(2, 2,
1698 LONG_DELAY_MS, MILLISECONDS,
1699 new ArrayBlockingQueue<Runnable>(10));
1700 final Collection<Callable<String>> emptyCollection
1701 = Collections.emptyList();
1702 try (PoolCleaner cleaner = cleaner(e)) {
1703 List<Future<String>> r =
1704 e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit());
1705 assertTrue(r.isEmpty());
1706 }
1707 }
1708
1709 /**
1710 * timed invokeAll(c) throws NPE if c has null elements
1711 */
1712 public void testTimedInvokeAll3() 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 l.add(null);
1721 try {
1722 e.invokeAll(l, randomTimeout(), randomTimeUnit());
1723 shouldThrow();
1724 } catch (NullPointerException success) {}
1725 }
1726 }
1727
1728 /**
1729 * get of element of invokeAll(c) throws exception on failed task
1730 */
1731 public void testTimedInvokeAll4() throws Exception {
1732 final ExecutorService e =
1733 new ThreadPoolExecutor(2, 2,
1734 LONG_DELAY_MS, MILLISECONDS,
1735 new ArrayBlockingQueue<Runnable>(10));
1736 try (PoolCleaner cleaner = cleaner(e)) {
1737 List<Callable<String>> l = new ArrayList<>();
1738 l.add(new NPETask());
1739 List<Future<String>> futures =
1740 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1741 assertEquals(1, futures.size());
1742 try {
1743 futures.get(0).get();
1744 shouldThrow();
1745 } catch (ExecutionException success) {
1746 assertTrue(success.getCause() instanceof NullPointerException);
1747 }
1748 }
1749 }
1750
1751 /**
1752 * timed invokeAll(c) returns results of all completed tasks
1753 */
1754 public void testTimedInvokeAll5() throws Exception {
1755 final ExecutorService e =
1756 new ThreadPoolExecutor(2, 2,
1757 LONG_DELAY_MS, MILLISECONDS,
1758 new ArrayBlockingQueue<Runnable>(10));
1759 try (PoolCleaner cleaner = cleaner(e)) {
1760 List<Callable<String>> l = new ArrayList<>();
1761 l.add(new StringTask());
1762 l.add(new StringTask());
1763 List<Future<String>> futures =
1764 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1765 assertEquals(2, futures.size());
1766 for (Future<String> future : futures)
1767 assertSame(TEST_STRING, future.get());
1768 }
1769 }
1770
1771 /**
1772 * timed invokeAll(c) cancels tasks not completed by timeout
1773 */
1774 public void testTimedInvokeAll6() throws Exception {
1775 for (long timeout = timeoutMillis();;) {
1776 final CountDownLatch done = new CountDownLatch(1);
1777 final Callable<String> waiter = new CheckedCallable<>() {
1778 public String realCall() {
1779 try { done.await(LONG_DELAY_MS, MILLISECONDS); }
1780 catch (InterruptedException ok) {}
1781 return "1"; }};
1782 final ExecutorService p =
1783 new ThreadPoolExecutor(2, 2,
1784 LONG_DELAY_MS, MILLISECONDS,
1785 new ArrayBlockingQueue<Runnable>(10));
1786 try (PoolCleaner cleaner = cleaner(p, done)) {
1787 List<Callable<String>> tasks = new ArrayList<>();
1788 tasks.add(new StringTask("0"));
1789 tasks.add(waiter);
1790 tasks.add(new StringTask("2"));
1791 long startTime = System.nanoTime();
1792 List<Future<String>> futures =
1793 p.invokeAll(tasks, timeout, MILLISECONDS);
1794 assertEquals(tasks.size(), futures.size());
1795 assertTrue(millisElapsedSince(startTime) >= timeout);
1796 for (Future<?> future : futures)
1797 assertTrue(future.isDone());
1798 assertTrue(futures.get(1).isCancelled());
1799 try {
1800 assertEquals("0", futures.get(0).get());
1801 assertEquals("2", futures.get(2).get());
1802 break;
1803 } catch (CancellationException retryWithLongerTimeout) {
1804 timeout *= 2;
1805 if (timeout >= LONG_DELAY_MS / 2)
1806 fail("expected exactly one task to be cancelled");
1807 }
1808 }
1809 }
1810 }
1811
1812 /**
1813 * Execution continues if there is at least one thread even if
1814 * thread factory fails to create more
1815 */
1816 public void testFailingThreadFactory() throws InterruptedException {
1817 final ExecutorService e =
1818 new ThreadPoolExecutor(100, 100,
1819 LONG_DELAY_MS, MILLISECONDS,
1820 new LinkedBlockingQueue<Runnable>(),
1821 new FailingThreadFactory());
1822 try (PoolCleaner cleaner = cleaner(e)) {
1823 final int TASKS = 100;
1824 final CountDownLatch done = new CountDownLatch(TASKS);
1825 for (int k = 0; k < TASKS; ++k)
1826 e.execute(new CheckedRunnable() {
1827 public void realRun() {
1828 done.countDown();
1829 }});
1830 await(done);
1831 }
1832 }
1833
1834 /**
1835 * allowsCoreThreadTimeOut is by default false.
1836 */
1837 public void testAllowsCoreThreadTimeOut() {
1838 final ThreadPoolExecutor p =
1839 new ThreadPoolExecutor(2, 2,
1840 1000, MILLISECONDS,
1841 new ArrayBlockingQueue<Runnable>(10));
1842 try (PoolCleaner cleaner = cleaner(p)) {
1843 assertFalse(p.allowsCoreThreadTimeOut());
1844 }
1845 }
1846
1847 /**
1848 * allowCoreThreadTimeOut(true) causes idle threads to time out
1849 */
1850 public void testAllowCoreThreadTimeOut_true() throws Exception {
1851 long keepAliveTime = timeoutMillis();
1852 final ThreadPoolExecutor p =
1853 new ThreadPoolExecutor(2, 10,
1854 keepAliveTime, MILLISECONDS,
1855 new ArrayBlockingQueue<Runnable>(10));
1856 try (PoolCleaner cleaner = cleaner(p)) {
1857 final CountDownLatch threadStarted = new CountDownLatch(1);
1858 p.allowCoreThreadTimeOut(true);
1859 p.execute(new CheckedRunnable() {
1860 public void realRun() {
1861 threadStarted.countDown();
1862 assertEquals(1, p.getPoolSize());
1863 }});
1864 await(threadStarted);
1865 delay(keepAliveTime);
1866 long startTime = System.nanoTime();
1867 while (p.getPoolSize() > 0
1868 && millisElapsedSince(startTime) < LONG_DELAY_MS)
1869 Thread.yield();
1870 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1871 assertEquals(0, p.getPoolSize());
1872 }
1873 }
1874
1875 /**
1876 * allowCoreThreadTimeOut(false) causes idle threads not to time out
1877 */
1878 public void testAllowCoreThreadTimeOut_false() throws Exception {
1879 long keepAliveTime = timeoutMillis();
1880 final ThreadPoolExecutor p =
1881 new ThreadPoolExecutor(2, 10,
1882 keepAliveTime, MILLISECONDS,
1883 new ArrayBlockingQueue<Runnable>(10));
1884 try (PoolCleaner cleaner = cleaner(p)) {
1885 final CountDownLatch threadStarted = new CountDownLatch(1);
1886 p.allowCoreThreadTimeOut(false);
1887 p.execute(new CheckedRunnable() {
1888 public void realRun() throws InterruptedException {
1889 threadStarted.countDown();
1890 assertTrue(p.getPoolSize() >= 1);
1891 }});
1892 delay(2 * keepAliveTime);
1893 assertTrue(p.getPoolSize() >= 1);
1894 }
1895 }
1896
1897 /**
1898 * execute allows the same task to be submitted multiple times, even
1899 * if rejected
1900 */
1901 public void testRejectedRecycledTask() throws InterruptedException {
1902 final int nTasks = 1000;
1903 final CountDownLatch done = new CountDownLatch(nTasks);
1904 final Runnable recycledTask = new Runnable() {
1905 public void run() {
1906 done.countDown();
1907 }};
1908 final ThreadPoolExecutor p =
1909 new ThreadPoolExecutor(1, 30,
1910 60, SECONDS,
1911 new ArrayBlockingQueue<Runnable>(30));
1912 try (PoolCleaner cleaner = cleaner(p)) {
1913 for (int i = 0; i < nTasks; ++i) {
1914 for (;;) {
1915 try {
1916 p.execute(recycledTask);
1917 break;
1918 }
1919 catch (RejectedExecutionException ignore) {}
1920 }
1921 }
1922 // enough time to run all tasks
1923 await(done, nTasks * SHORT_DELAY_MS);
1924 }
1925 }
1926
1927 /**
1928 * get(cancelled task) throws CancellationException
1929 */
1930 public void testGet_cancelled() throws Exception {
1931 final CountDownLatch done = new CountDownLatch(1);
1932 final ExecutorService e =
1933 new ThreadPoolExecutor(1, 1,
1934 LONG_DELAY_MS, MILLISECONDS,
1935 new LinkedBlockingQueue<Runnable>());
1936 try (PoolCleaner cleaner = cleaner(e, done)) {
1937 final CountDownLatch blockerStarted = new CountDownLatch(1);
1938 final List<Future<?>> futures = new ArrayList<>();
1939 for (int i = 0; i < 2; i++) {
1940 Runnable r = new CheckedRunnable() { public void realRun()
1941 throws Throwable {
1942 blockerStarted.countDown();
1943 assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
1944 }};
1945 futures.add(e.submit(r));
1946 }
1947 await(blockerStarted);
1948 for (Future<?> future : futures) future.cancel(false);
1949 for (Future<?> future : futures) {
1950 try {
1951 future.get();
1952 shouldThrow();
1953 } catch (CancellationException success) {}
1954 try {
1955 future.get(LONG_DELAY_MS, MILLISECONDS);
1956 shouldThrow();
1957 } catch (CancellationException success) {}
1958 assertTrue(future.isCancelled());
1959 assertTrue(future.isDone());
1960 }
1961 }
1962 }
1963
1964 /** Directly test simple ThreadPoolExecutor RejectedExecutionHandlers. */
1965 public void testStandardRejectedExecutionHandlers() {
1966 final ThreadPoolExecutor p =
1967 new ThreadPoolExecutor(1, 1, 1, SECONDS,
1968 new ArrayBlockingQueue<Runnable>(1));
1969 final AtomicReference<Thread> thread = new AtomicReference<>();
1970 final Runnable r = new Runnable() { public void run() {
1971 thread.set(Thread.currentThread()); }};
1972
1973 try {
1974 new AbortPolicy().rejectedExecution(r, p);
1975 shouldThrow();
1976 } catch (RejectedExecutionException success) {}
1977 assertNull(thread.get());
1978
1979 new DiscardPolicy().rejectedExecution(r, p);
1980 assertNull(thread.get());
1981
1982 new CallerRunsPolicy().rejectedExecution(r, p);
1983 assertSame(Thread.currentThread(), thread.get());
1984
1985 // check that pool was not perturbed by handlers
1986 assertTrue(p.getRejectedExecutionHandler() instanceof AbortPolicy);
1987 assertEquals(0, p.getTaskCount());
1988 assertTrue(p.getQueue().isEmpty());
1989 }
1990
1991 public void testThreadFactoryReturnsTerminatedThread_shouldThrow() {
1992 if (!testImplementationDetails)
1993 return;
1994
1995 ThreadFactory returnsTerminatedThread = runnableIgnored -> {
1996 Thread thread = new Thread(() -> {});
1997 thread.start();
1998 try { thread.join(); }
1999 catch (InterruptedException ex) { throw new Error(ex); }
2000 return thread;
2001 };
2002 ThreadPoolExecutor p =
2003 new ThreadPoolExecutor(1, 1, 1, SECONDS,
2004 new ArrayBlockingQueue<Runnable>(1),
2005 returnsTerminatedThread);
2006 try (PoolCleaner cleaner = cleaner(p)) {
2007 assertThrows(IllegalThreadStateException.class,
2008 () -> p.execute(() -> {}));
2009 }
2010 }
2011
2012 public void testThreadFactoryReturnsStartedThread_shouldThrow() {
2013 if (!testImplementationDetails)
2014 return;
2015
2016 CountDownLatch latch = new CountDownLatch(1);
2017 Runnable awaitLatch = () -> {
2018 try { latch.await(); }
2019 catch (InterruptedException ex) { throw new Error(ex); }};
2020 ThreadFactory returnsStartedThread = runnable -> {
2021 Thread thread = new Thread(awaitLatch);
2022 thread.start();
2023 return thread;
2024 };
2025 ThreadPoolExecutor p =
2026 new ThreadPoolExecutor(1, 1, 1, SECONDS,
2027 new ArrayBlockingQueue<Runnable>(1),
2028 returnsStartedThread);
2029 try (PoolCleaner cleaner = cleaner(p)) {
2030 assertThrows(IllegalThreadStateException.class,
2031 () -> p.execute(() -> {}));
2032 latch.countDown();
2033 }
2034 }
2035
2036 }