ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorTest.java
Revision: 1.125
Committed: Wed Apr 3 20:55:45 2019 UTC (5 years, 1 month ago) by jsr166
Branch: MAIN
Changes since 1.124: +45 -0 lines
Log Message:
8221892: ThreadPoolExecutor: Thread.isAlive() is not equivalent to not being startable

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); // ensure quiescence
1063 t.interrupt();
1064 awaitTermination(t);
1065 }
1066 }
1067
1068 /**
1069 * Submitted tasks are rejected when saturated or shutdown
1070 */
1071 public void testSubmittedTasksRejectedWhenSaturatedOrShutdown() throws InterruptedException {
1072 final ThreadPoolExecutor p = new ThreadPoolExecutor(
1073 1, 1, 1, SECONDS, new ArrayBlockingQueue<Runnable>(1));
1074 final int saturatedSize = saturatedSize(p);
1075 final ThreadLocalRandom rnd = ThreadLocalRandom.current();
1076 final CountDownLatch threadsStarted = new CountDownLatch(p.getMaximumPoolSize());
1077 final CountDownLatch done = new CountDownLatch(1);
1078 final Runnable r = () -> {
1079 threadsStarted.countDown();
1080 for (;;) {
1081 try {
1082 done.await();
1083 return;
1084 } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
1085 }};
1086 final Callable<Boolean> c = () -> {
1087 threadsStarted.countDown();
1088 for (;;) {
1089 try {
1090 done.await();
1091 return Boolean.TRUE;
1092 } catch (InterruptedException shutdownNowDeliberatelyIgnored) {}
1093 }};
1094 final boolean shutdownNow = rnd.nextBoolean();
1095
1096 try (PoolCleaner cleaner = cleaner(p, done)) {
1097 // saturate
1098 for (int i = saturatedSize; i--> 0; ) {
1099 switch (rnd.nextInt(4)) {
1100 case 0: p.execute(r); break;
1101 case 1: assertFalse(p.submit(r).isDone()); break;
1102 case 2: assertFalse(p.submit(r, Boolean.TRUE).isDone()); break;
1103 case 3: assertFalse(p.submit(c).isDone()); break;
1104 }
1105 }
1106
1107 await(threadsStarted);
1108 assertTaskSubmissionsAreRejected(p);
1109
1110 if (shutdownNow)
1111 p.shutdownNow();
1112 else
1113 p.shutdown();
1114 // Pool is shutdown, but not yet terminated
1115 assertTaskSubmissionsAreRejected(p);
1116 assertFalse(p.isTerminated());
1117
1118 done.countDown(); // release blocking tasks
1119 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
1120
1121 assertTaskSubmissionsAreRejected(p);
1122 }
1123 assertEquals(saturatedSize(p)
1124 - (shutdownNow ? p.getQueue().remainingCapacity() : 0),
1125 p.getCompletedTaskCount());
1126 }
1127
1128 /**
1129 * executor using DiscardOldestPolicy drops oldest task if saturated.
1130 */
1131 public void testSaturatedExecute_DiscardOldestPolicy() {
1132 final CountDownLatch done = new CountDownLatch(1);
1133 LatchAwaiter r1 = awaiter(done);
1134 LatchAwaiter r2 = awaiter(done);
1135 LatchAwaiter r3 = awaiter(done);
1136 final ThreadPoolExecutor p =
1137 new ThreadPoolExecutor(1, 1,
1138 LONG_DELAY_MS, MILLISECONDS,
1139 new ArrayBlockingQueue<Runnable>(1),
1140 new DiscardOldestPolicy());
1141 try (PoolCleaner cleaner = cleaner(p, done)) {
1142 assertEquals(LatchAwaiter.NEW, r1.state);
1143 assertEquals(LatchAwaiter.NEW, r2.state);
1144 assertEquals(LatchAwaiter.NEW, r3.state);
1145 p.execute(r1);
1146 p.execute(r2);
1147 assertTrue(p.getQueue().contains(r2));
1148 p.execute(r3);
1149 assertFalse(p.getQueue().contains(r2));
1150 assertTrue(p.getQueue().contains(r3));
1151 }
1152 assertEquals(LatchAwaiter.DONE, r1.state);
1153 assertEquals(LatchAwaiter.NEW, r2.state);
1154 assertEquals(LatchAwaiter.DONE, r3.state);
1155 }
1156
1157 /**
1158 * execute using DiscardOldestPolicy drops task on shutdown
1159 */
1160 public void testDiscardOldestOnShutdown() {
1161 final ThreadPoolExecutor p =
1162 new ThreadPoolExecutor(1, 1,
1163 LONG_DELAY_MS, MILLISECONDS,
1164 new ArrayBlockingQueue<Runnable>(1),
1165 new DiscardOldestPolicy());
1166
1167 try { p.shutdown(); } catch (SecurityException ok) { return; }
1168 try (PoolCleaner cleaner = cleaner(p)) {
1169 TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1170 p.execute(r);
1171 assertFalse(r.done);
1172 }
1173 }
1174
1175 /**
1176 * Submitting null tasks throws NullPointerException
1177 */
1178 public void testNullTaskSubmission() {
1179 final ThreadPoolExecutor p =
1180 new ThreadPoolExecutor(1, 2,
1181 1L, SECONDS,
1182 new ArrayBlockingQueue<Runnable>(10));
1183 try (PoolCleaner cleaner = cleaner(p)) {
1184 assertNullTaskSubmissionThrowsNullPointerException(p);
1185 }
1186 }
1187
1188 /**
1189 * setCorePoolSize of negative value throws IllegalArgumentException
1190 */
1191 public void testCorePoolSizeIllegalArgumentException() {
1192 final ThreadPoolExecutor p =
1193 new ThreadPoolExecutor(1, 2,
1194 LONG_DELAY_MS, MILLISECONDS,
1195 new ArrayBlockingQueue<Runnable>(10));
1196 try (PoolCleaner cleaner = cleaner(p)) {
1197 try {
1198 p.setCorePoolSize(-1);
1199 shouldThrow();
1200 } catch (IllegalArgumentException success) {}
1201 }
1202 }
1203
1204 /**
1205 * setMaximumPoolSize(int) throws IllegalArgumentException if
1206 * given a value less the core pool size
1207 */
1208 public void testMaximumPoolSizeIllegalArgumentException() {
1209 final ThreadPoolExecutor p =
1210 new ThreadPoolExecutor(2, 3,
1211 LONG_DELAY_MS, MILLISECONDS,
1212 new ArrayBlockingQueue<Runnable>(10));
1213 try (PoolCleaner cleaner = cleaner(p)) {
1214 try {
1215 p.setMaximumPoolSize(1);
1216 shouldThrow();
1217 } catch (IllegalArgumentException success) {}
1218 }
1219 }
1220
1221 /**
1222 * setMaximumPoolSize throws IllegalArgumentException
1223 * if given a negative value
1224 */
1225 public void testMaximumPoolSizeIllegalArgumentException2() {
1226 final ThreadPoolExecutor p =
1227 new ThreadPoolExecutor(2, 3,
1228 LONG_DELAY_MS, MILLISECONDS,
1229 new ArrayBlockingQueue<Runnable>(10));
1230 try (PoolCleaner cleaner = cleaner(p)) {
1231 try {
1232 p.setMaximumPoolSize(-1);
1233 shouldThrow();
1234 } catch (IllegalArgumentException success) {}
1235 }
1236 }
1237
1238 /**
1239 * Configuration changes that allow core pool size greater than
1240 * max pool size result in IllegalArgumentException.
1241 */
1242 public void testPoolSizeInvariants() {
1243 final ThreadPoolExecutor p =
1244 new ThreadPoolExecutor(1, 1,
1245 LONG_DELAY_MS, MILLISECONDS,
1246 new ArrayBlockingQueue<Runnable>(10));
1247 try (PoolCleaner cleaner = cleaner(p)) {
1248 for (int s = 1; s < 5; s++) {
1249 p.setMaximumPoolSize(s);
1250 p.setCorePoolSize(s);
1251 try {
1252 p.setMaximumPoolSize(s - 1);
1253 shouldThrow();
1254 } catch (IllegalArgumentException success) {}
1255 assertEquals(s, p.getCorePoolSize());
1256 assertEquals(s, p.getMaximumPoolSize());
1257 try {
1258 p.setCorePoolSize(s + 1);
1259 shouldThrow();
1260 } catch (IllegalArgumentException success) {}
1261 assertEquals(s, p.getCorePoolSize());
1262 assertEquals(s, p.getMaximumPoolSize());
1263 }
1264 }
1265 }
1266
1267 /**
1268 * setKeepAliveTime throws IllegalArgumentException
1269 * when given a negative value
1270 */
1271 public void testKeepAliveTimeIllegalArgumentException() {
1272 final ThreadPoolExecutor p =
1273 new ThreadPoolExecutor(2, 3,
1274 LONG_DELAY_MS, MILLISECONDS,
1275 new ArrayBlockingQueue<Runnable>(10));
1276 try (PoolCleaner cleaner = cleaner(p)) {
1277 try {
1278 p.setKeepAliveTime(-1, MILLISECONDS);
1279 shouldThrow();
1280 } catch (IllegalArgumentException success) {}
1281 }
1282 }
1283
1284 /**
1285 * terminated() is called on termination
1286 */
1287 public void testTerminated() {
1288 ExtendedTPE p = new ExtendedTPE();
1289 try (PoolCleaner cleaner = cleaner(p)) {
1290 try { p.shutdown(); } catch (SecurityException ok) { return; }
1291 assertTrue(p.terminatedCalled());
1292 assertTrue(p.isShutdown());
1293 }
1294 }
1295
1296 /**
1297 * beforeExecute and afterExecute are called when executing task
1298 */
1299 public void testBeforeAfter() throws InterruptedException {
1300 ExtendedTPE p = new ExtendedTPE();
1301 try (PoolCleaner cleaner = cleaner(p)) {
1302 final CountDownLatch done = new CountDownLatch(1);
1303 p.execute(new CheckedRunnable() {
1304 public void realRun() {
1305 done.countDown();
1306 }});
1307 await(p.afterCalled);
1308 assertEquals(0, done.getCount());
1309 assertTrue(p.afterCalled());
1310 assertTrue(p.beforeCalled());
1311 }
1312 }
1313
1314 /**
1315 * completed submit of callable returns result
1316 */
1317 public void testSubmitCallable() throws Exception {
1318 final ExecutorService e =
1319 new ThreadPoolExecutor(2, 2,
1320 LONG_DELAY_MS, MILLISECONDS,
1321 new ArrayBlockingQueue<Runnable>(10));
1322 try (PoolCleaner cleaner = cleaner(e)) {
1323 Future<String> future = e.submit(new StringTask());
1324 String result = future.get();
1325 assertSame(TEST_STRING, result);
1326 }
1327 }
1328
1329 /**
1330 * completed submit of runnable returns successfully
1331 */
1332 public void testSubmitRunnable() throws Exception {
1333 final ExecutorService e =
1334 new ThreadPoolExecutor(2, 2,
1335 LONG_DELAY_MS, MILLISECONDS,
1336 new ArrayBlockingQueue<Runnable>(10));
1337 try (PoolCleaner cleaner = cleaner(e)) {
1338 Future<?> future = e.submit(new NoOpRunnable());
1339 future.get();
1340 assertTrue(future.isDone());
1341 }
1342 }
1343
1344 /**
1345 * completed submit of (runnable, result) returns result
1346 */
1347 public void testSubmitRunnable2() throws Exception {
1348 final ExecutorService e =
1349 new ThreadPoolExecutor(2, 2,
1350 LONG_DELAY_MS, MILLISECONDS,
1351 new ArrayBlockingQueue<Runnable>(10));
1352 try (PoolCleaner cleaner = cleaner(e)) {
1353 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
1354 String result = future.get();
1355 assertSame(TEST_STRING, result);
1356 }
1357 }
1358
1359 /**
1360 * invokeAny(null) throws NPE
1361 */
1362 public void testInvokeAny1() throws Exception {
1363 final ExecutorService e =
1364 new ThreadPoolExecutor(2, 2,
1365 LONG_DELAY_MS, MILLISECONDS,
1366 new ArrayBlockingQueue<Runnable>(10));
1367 try (PoolCleaner cleaner = cleaner(e)) {
1368 try {
1369 e.invokeAny(null);
1370 shouldThrow();
1371 } catch (NullPointerException success) {}
1372 }
1373 }
1374
1375 /**
1376 * invokeAny(empty collection) throws IllegalArgumentException
1377 */
1378 public void testInvokeAny2() throws Exception {
1379 final ExecutorService e =
1380 new ThreadPoolExecutor(2, 2,
1381 LONG_DELAY_MS, MILLISECONDS,
1382 new ArrayBlockingQueue<Runnable>(10));
1383 try (PoolCleaner cleaner = cleaner(e)) {
1384 try {
1385 e.invokeAny(new ArrayList<Callable<String>>());
1386 shouldThrow();
1387 } catch (IllegalArgumentException success) {}
1388 }
1389 }
1390
1391 /**
1392 * invokeAny(c) throws NPE if c has null elements
1393 */
1394 public void testInvokeAny3() throws Exception {
1395 final CountDownLatch latch = new CountDownLatch(1);
1396 final ExecutorService e =
1397 new ThreadPoolExecutor(2, 2,
1398 LONG_DELAY_MS, MILLISECONDS,
1399 new ArrayBlockingQueue<Runnable>(10));
1400 try (PoolCleaner cleaner = cleaner(e)) {
1401 List<Callable<String>> l = new ArrayList<>();
1402 l.add(latchAwaitingStringTask(latch));
1403 l.add(null);
1404 try {
1405 e.invokeAny(l);
1406 shouldThrow();
1407 } catch (NullPointerException success) {}
1408 latch.countDown();
1409 }
1410 }
1411
1412 /**
1413 * invokeAny(c) throws ExecutionException if no task completes
1414 */
1415 public void testInvokeAny4() throws Exception {
1416 final ExecutorService e =
1417 new ThreadPoolExecutor(2, 2,
1418 LONG_DELAY_MS, MILLISECONDS,
1419 new ArrayBlockingQueue<Runnable>(10));
1420 try (PoolCleaner cleaner = cleaner(e)) {
1421 List<Callable<String>> l = new ArrayList<>();
1422 l.add(new NPETask());
1423 try {
1424 e.invokeAny(l);
1425 shouldThrow();
1426 } catch (ExecutionException success) {
1427 assertTrue(success.getCause() instanceof NullPointerException);
1428 }
1429 }
1430 }
1431
1432 /**
1433 * invokeAny(c) returns result of some task
1434 */
1435 public void testInvokeAny5() throws Exception {
1436 final ExecutorService e =
1437 new ThreadPoolExecutor(2, 2,
1438 LONG_DELAY_MS, MILLISECONDS,
1439 new ArrayBlockingQueue<Runnable>(10));
1440 try (PoolCleaner cleaner = cleaner(e)) {
1441 List<Callable<String>> l = new ArrayList<>();
1442 l.add(new StringTask());
1443 l.add(new StringTask());
1444 String result = e.invokeAny(l);
1445 assertSame(TEST_STRING, result);
1446 }
1447 }
1448
1449 /**
1450 * invokeAll(null) throws NPE
1451 */
1452 public void testInvokeAll1() throws Exception {
1453 final ExecutorService e =
1454 new ThreadPoolExecutor(2, 2,
1455 LONG_DELAY_MS, MILLISECONDS,
1456 new ArrayBlockingQueue<Runnable>(10));
1457 try (PoolCleaner cleaner = cleaner(e)) {
1458 try {
1459 e.invokeAll(null);
1460 shouldThrow();
1461 } catch (NullPointerException success) {}
1462 }
1463 }
1464
1465 /**
1466 * invokeAll(empty collection) returns empty list
1467 */
1468 public void testInvokeAll2() throws InterruptedException {
1469 final ExecutorService e =
1470 new ThreadPoolExecutor(2, 2,
1471 LONG_DELAY_MS, MILLISECONDS,
1472 new ArrayBlockingQueue<Runnable>(10));
1473 final Collection<Callable<String>> emptyCollection
1474 = Collections.emptyList();
1475 try (PoolCleaner cleaner = cleaner(e)) {
1476 List<Future<String>> r = e.invokeAll(emptyCollection);
1477 assertTrue(r.isEmpty());
1478 }
1479 }
1480
1481 /**
1482 * invokeAll(c) throws NPE if c has null elements
1483 */
1484 public void testInvokeAll3() 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 List<Callable<String>> l = new ArrayList<>();
1491 l.add(new StringTask());
1492 l.add(null);
1493 try {
1494 e.invokeAll(l);
1495 shouldThrow();
1496 } catch (NullPointerException success) {}
1497 }
1498 }
1499
1500 /**
1501 * get of element of invokeAll(c) throws exception on failed task
1502 */
1503 public void testInvokeAll4() throws Exception {
1504 final ExecutorService e =
1505 new ThreadPoolExecutor(2, 2,
1506 LONG_DELAY_MS, MILLISECONDS,
1507 new ArrayBlockingQueue<Runnable>(10));
1508 try (PoolCleaner cleaner = cleaner(e)) {
1509 List<Callable<String>> l = new ArrayList<>();
1510 l.add(new NPETask());
1511 List<Future<String>> futures = e.invokeAll(l);
1512 assertEquals(1, futures.size());
1513 try {
1514 futures.get(0).get();
1515 shouldThrow();
1516 } catch (ExecutionException success) {
1517 assertTrue(success.getCause() instanceof NullPointerException);
1518 }
1519 }
1520 }
1521
1522 /**
1523 * invokeAll(c) returns results of all completed tasks
1524 */
1525 public void testInvokeAll5() throws Exception {
1526 final ExecutorService e =
1527 new ThreadPoolExecutor(2, 2,
1528 LONG_DELAY_MS, MILLISECONDS,
1529 new ArrayBlockingQueue<Runnable>(10));
1530 try (PoolCleaner cleaner = cleaner(e)) {
1531 List<Callable<String>> l = new ArrayList<>();
1532 l.add(new StringTask());
1533 l.add(new StringTask());
1534 List<Future<String>> futures = e.invokeAll(l);
1535 assertEquals(2, futures.size());
1536 for (Future<String> future : futures)
1537 assertSame(TEST_STRING, future.get());
1538 }
1539 }
1540
1541 /**
1542 * timed invokeAny(null) throws NPE
1543 */
1544 public void testTimedInvokeAny1() throws Exception {
1545 final ExecutorService e =
1546 new ThreadPoolExecutor(2, 2,
1547 LONG_DELAY_MS, MILLISECONDS,
1548 new ArrayBlockingQueue<Runnable>(10));
1549 try (PoolCleaner cleaner = cleaner(e)) {
1550 try {
1551 e.invokeAny(null, randomTimeout(), randomTimeUnit());
1552 shouldThrow();
1553 } catch (NullPointerException success) {}
1554 }
1555 }
1556
1557 /**
1558 * timed invokeAny(,,null) throws NPE
1559 */
1560 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
1561 final ExecutorService e =
1562 new ThreadPoolExecutor(2, 2,
1563 LONG_DELAY_MS, MILLISECONDS,
1564 new ArrayBlockingQueue<Runnable>(10));
1565 try (PoolCleaner cleaner = cleaner(e)) {
1566 List<Callable<String>> l = new ArrayList<>();
1567 l.add(new StringTask());
1568 try {
1569 e.invokeAny(l, randomTimeout(), null);
1570 shouldThrow();
1571 } catch (NullPointerException success) {}
1572 }
1573 }
1574
1575 /**
1576 * timed invokeAny(empty collection) throws IllegalArgumentException
1577 */
1578 public void testTimedInvokeAny2() throws Exception {
1579 final ExecutorService e =
1580 new ThreadPoolExecutor(2, 2,
1581 LONG_DELAY_MS, MILLISECONDS,
1582 new ArrayBlockingQueue<Runnable>(10));
1583 try (PoolCleaner cleaner = cleaner(e)) {
1584 try {
1585 e.invokeAny(new ArrayList<Callable<String>>(),
1586 randomTimeout(), randomTimeUnit());
1587 shouldThrow();
1588 } catch (IllegalArgumentException success) {}
1589 }
1590 }
1591
1592 /**
1593 * timed invokeAny(c) throws NullPointerException if c has null elements
1594 */
1595 public void testTimedInvokeAny3() throws Exception {
1596 final CountDownLatch latch = new CountDownLatch(1);
1597 final ExecutorService e =
1598 new ThreadPoolExecutor(2, 2,
1599 LONG_DELAY_MS, MILLISECONDS,
1600 new ArrayBlockingQueue<Runnable>(10));
1601 try (PoolCleaner cleaner = cleaner(e)) {
1602 List<Callable<String>> l = new ArrayList<>();
1603 l.add(latchAwaitingStringTask(latch));
1604 l.add(null);
1605 try {
1606 e.invokeAny(l, randomTimeout(), randomTimeUnit());
1607 shouldThrow();
1608 } catch (NullPointerException success) {}
1609 latch.countDown();
1610 }
1611 }
1612
1613 /**
1614 * timed invokeAny(c) throws ExecutionException if no task completes
1615 */
1616 public void testTimedInvokeAny4() throws Exception {
1617 final ExecutorService e =
1618 new ThreadPoolExecutor(2, 2,
1619 LONG_DELAY_MS, MILLISECONDS,
1620 new ArrayBlockingQueue<Runnable>(10));
1621 try (PoolCleaner cleaner = cleaner(e)) {
1622 long startTime = System.nanoTime();
1623 List<Callable<String>> l = new ArrayList<>();
1624 l.add(new NPETask());
1625 try {
1626 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1627 shouldThrow();
1628 } catch (ExecutionException success) {
1629 assertTrue(success.getCause() instanceof NullPointerException);
1630 }
1631 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1632 }
1633 }
1634
1635 /**
1636 * timed invokeAny(c) returns result of some task
1637 */
1638 public void testTimedInvokeAny5() throws Exception {
1639 final ExecutorService e =
1640 new ThreadPoolExecutor(2, 2,
1641 LONG_DELAY_MS, MILLISECONDS,
1642 new ArrayBlockingQueue<Runnable>(10));
1643 try (PoolCleaner cleaner = cleaner(e)) {
1644 long startTime = System.nanoTime();
1645 List<Callable<String>> l = new ArrayList<>();
1646 l.add(new StringTask());
1647 l.add(new StringTask());
1648 String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1649 assertSame(TEST_STRING, result);
1650 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1651 }
1652 }
1653
1654 /**
1655 * timed invokeAll(null) throws NPE
1656 */
1657 public void testTimedInvokeAll1() throws Exception {
1658 final ExecutorService e =
1659 new ThreadPoolExecutor(2, 2,
1660 LONG_DELAY_MS, MILLISECONDS,
1661 new ArrayBlockingQueue<Runnable>(10));
1662 try (PoolCleaner cleaner = cleaner(e)) {
1663 try {
1664 e.invokeAll(null, randomTimeout(), randomTimeUnit());
1665 shouldThrow();
1666 } catch (NullPointerException success) {}
1667 }
1668 }
1669
1670 /**
1671 * timed invokeAll(,,null) throws NPE
1672 */
1673 public void testTimedInvokeAllNullTimeUnit() throws Exception {
1674 final ExecutorService e =
1675 new ThreadPoolExecutor(2, 2,
1676 LONG_DELAY_MS, MILLISECONDS,
1677 new ArrayBlockingQueue<Runnable>(10));
1678 try (PoolCleaner cleaner = cleaner(e)) {
1679 List<Callable<String>> l = new ArrayList<>();
1680 l.add(new StringTask());
1681 try {
1682 e.invokeAll(l, randomTimeout(), null);
1683 shouldThrow();
1684 } catch (NullPointerException success) {}
1685 }
1686 }
1687
1688 /**
1689 * timed invokeAll(empty collection) returns empty list
1690 */
1691 public void testTimedInvokeAll2() throws InterruptedException {
1692 final ExecutorService e =
1693 new ThreadPoolExecutor(2, 2,
1694 LONG_DELAY_MS, MILLISECONDS,
1695 new ArrayBlockingQueue<Runnable>(10));
1696 final Collection<Callable<String>> emptyCollection
1697 = Collections.emptyList();
1698 try (PoolCleaner cleaner = cleaner(e)) {
1699 List<Future<String>> r =
1700 e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit());
1701 assertTrue(r.isEmpty());
1702 }
1703 }
1704
1705 /**
1706 * timed invokeAll(c) throws NPE if c has null elements
1707 */
1708 public void testTimedInvokeAll3() throws Exception {
1709 final ExecutorService e =
1710 new ThreadPoolExecutor(2, 2,
1711 LONG_DELAY_MS, MILLISECONDS,
1712 new ArrayBlockingQueue<Runnable>(10));
1713 try (PoolCleaner cleaner = cleaner(e)) {
1714 List<Callable<String>> l = new ArrayList<>();
1715 l.add(new StringTask());
1716 l.add(null);
1717 try {
1718 e.invokeAll(l, randomTimeout(), randomTimeUnit());
1719 shouldThrow();
1720 } catch (NullPointerException success) {}
1721 }
1722 }
1723
1724 /**
1725 * get of element of invokeAll(c) throws exception on failed task
1726 */
1727 public void testTimedInvokeAll4() throws Exception {
1728 final ExecutorService e =
1729 new ThreadPoolExecutor(2, 2,
1730 LONG_DELAY_MS, MILLISECONDS,
1731 new ArrayBlockingQueue<Runnable>(10));
1732 try (PoolCleaner cleaner = cleaner(e)) {
1733 List<Callable<String>> l = new ArrayList<>();
1734 l.add(new NPETask());
1735 List<Future<String>> futures =
1736 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1737 assertEquals(1, futures.size());
1738 try {
1739 futures.get(0).get();
1740 shouldThrow();
1741 } catch (ExecutionException success) {
1742 assertTrue(success.getCause() instanceof NullPointerException);
1743 }
1744 }
1745 }
1746
1747 /**
1748 * timed invokeAll(c) returns results of all completed tasks
1749 */
1750 public void testTimedInvokeAll5() throws Exception {
1751 final ExecutorService e =
1752 new ThreadPoolExecutor(2, 2,
1753 LONG_DELAY_MS, MILLISECONDS,
1754 new ArrayBlockingQueue<Runnable>(10));
1755 try (PoolCleaner cleaner = cleaner(e)) {
1756 List<Callable<String>> l = new ArrayList<>();
1757 l.add(new StringTask());
1758 l.add(new StringTask());
1759 List<Future<String>> futures =
1760 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1761 assertEquals(2, futures.size());
1762 for (Future<String> future : futures)
1763 assertSame(TEST_STRING, future.get());
1764 }
1765 }
1766
1767 /**
1768 * timed invokeAll(c) cancels tasks not completed by timeout
1769 */
1770 public void testTimedInvokeAll6() throws Exception {
1771 for (long timeout = timeoutMillis();;) {
1772 final CountDownLatch done = new CountDownLatch(1);
1773 final Callable<String> waiter = new CheckedCallable<String>() {
1774 public String realCall() {
1775 try { done.await(LONG_DELAY_MS, MILLISECONDS); }
1776 catch (InterruptedException ok) {}
1777 return "1"; }};
1778 final ExecutorService p =
1779 new ThreadPoolExecutor(2, 2,
1780 LONG_DELAY_MS, MILLISECONDS,
1781 new ArrayBlockingQueue<Runnable>(10));
1782 try (PoolCleaner cleaner = cleaner(p, done)) {
1783 List<Callable<String>> tasks = new ArrayList<>();
1784 tasks.add(new StringTask("0"));
1785 tasks.add(waiter);
1786 tasks.add(new StringTask("2"));
1787 long startTime = System.nanoTime();
1788 List<Future<String>> futures =
1789 p.invokeAll(tasks, timeout, MILLISECONDS);
1790 assertEquals(tasks.size(), futures.size());
1791 assertTrue(millisElapsedSince(startTime) >= timeout);
1792 for (Future future : futures)
1793 assertTrue(future.isDone());
1794 assertTrue(futures.get(1).isCancelled());
1795 try {
1796 assertEquals("0", futures.get(0).get());
1797 assertEquals("2", futures.get(2).get());
1798 break;
1799 } catch (CancellationException retryWithLongerTimeout) {
1800 timeout *= 2;
1801 if (timeout >= LONG_DELAY_MS / 2)
1802 fail("expected exactly one task to be cancelled");
1803 }
1804 }
1805 }
1806 }
1807
1808 /**
1809 * Execution continues if there is at least one thread even if
1810 * thread factory fails to create more
1811 */
1812 public void testFailingThreadFactory() throws InterruptedException {
1813 final ExecutorService e =
1814 new ThreadPoolExecutor(100, 100,
1815 LONG_DELAY_MS, MILLISECONDS,
1816 new LinkedBlockingQueue<Runnable>(),
1817 new FailingThreadFactory());
1818 try (PoolCleaner cleaner = cleaner(e)) {
1819 final int TASKS = 100;
1820 final CountDownLatch done = new CountDownLatch(TASKS);
1821 for (int k = 0; k < TASKS; ++k)
1822 e.execute(new CheckedRunnable() {
1823 public void realRun() {
1824 done.countDown();
1825 }});
1826 await(done);
1827 }
1828 }
1829
1830 /**
1831 * allowsCoreThreadTimeOut is by default false.
1832 */
1833 public void testAllowsCoreThreadTimeOut() {
1834 final ThreadPoolExecutor p =
1835 new ThreadPoolExecutor(2, 2,
1836 1000, MILLISECONDS,
1837 new ArrayBlockingQueue<Runnable>(10));
1838 try (PoolCleaner cleaner = cleaner(p)) {
1839 assertFalse(p.allowsCoreThreadTimeOut());
1840 }
1841 }
1842
1843 /**
1844 * allowCoreThreadTimeOut(true) causes idle threads to time out
1845 */
1846 public void testAllowCoreThreadTimeOut_true() throws Exception {
1847 long keepAliveTime = timeoutMillis();
1848 final ThreadPoolExecutor p =
1849 new ThreadPoolExecutor(2, 10,
1850 keepAliveTime, MILLISECONDS,
1851 new ArrayBlockingQueue<Runnable>(10));
1852 try (PoolCleaner cleaner = cleaner(p)) {
1853 final CountDownLatch threadStarted = new CountDownLatch(1);
1854 p.allowCoreThreadTimeOut(true);
1855 p.execute(new CheckedRunnable() {
1856 public void realRun() {
1857 threadStarted.countDown();
1858 assertEquals(1, p.getPoolSize());
1859 }});
1860 await(threadStarted);
1861 delay(keepAliveTime);
1862 long startTime = System.nanoTime();
1863 while (p.getPoolSize() > 0
1864 && millisElapsedSince(startTime) < LONG_DELAY_MS)
1865 Thread.yield();
1866 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1867 assertEquals(0, p.getPoolSize());
1868 }
1869 }
1870
1871 /**
1872 * allowCoreThreadTimeOut(false) causes idle threads not to time out
1873 */
1874 public void testAllowCoreThreadTimeOut_false() throws Exception {
1875 long keepAliveTime = timeoutMillis();
1876 final ThreadPoolExecutor p =
1877 new ThreadPoolExecutor(2, 10,
1878 keepAliveTime, MILLISECONDS,
1879 new ArrayBlockingQueue<Runnable>(10));
1880 try (PoolCleaner cleaner = cleaner(p)) {
1881 final CountDownLatch threadStarted = new CountDownLatch(1);
1882 p.allowCoreThreadTimeOut(false);
1883 p.execute(new CheckedRunnable() {
1884 public void realRun() throws InterruptedException {
1885 threadStarted.countDown();
1886 assertTrue(p.getPoolSize() >= 1);
1887 }});
1888 delay(2 * keepAliveTime);
1889 assertTrue(p.getPoolSize() >= 1);
1890 }
1891 }
1892
1893 /**
1894 * execute allows the same task to be submitted multiple times, even
1895 * if rejected
1896 */
1897 public void testRejectedRecycledTask() throws InterruptedException {
1898 final int nTasks = 1000;
1899 final CountDownLatch done = new CountDownLatch(nTasks);
1900 final Runnable recycledTask = new Runnable() {
1901 public void run() {
1902 done.countDown();
1903 }};
1904 final ThreadPoolExecutor p =
1905 new ThreadPoolExecutor(1, 30,
1906 60, SECONDS,
1907 new ArrayBlockingQueue(30));
1908 try (PoolCleaner cleaner = cleaner(p)) {
1909 for (int i = 0; i < nTasks; ++i) {
1910 for (;;) {
1911 try {
1912 p.execute(recycledTask);
1913 break;
1914 }
1915 catch (RejectedExecutionException ignore) {}
1916 }
1917 }
1918 // enough time to run all tasks
1919 await(done, nTasks * SHORT_DELAY_MS);
1920 }
1921 }
1922
1923 /**
1924 * get(cancelled task) throws CancellationException
1925 */
1926 public void testGet_cancelled() throws Exception {
1927 final CountDownLatch done = new CountDownLatch(1);
1928 final ExecutorService e =
1929 new ThreadPoolExecutor(1, 1,
1930 LONG_DELAY_MS, MILLISECONDS,
1931 new LinkedBlockingQueue<Runnable>());
1932 try (PoolCleaner cleaner = cleaner(e, done)) {
1933 final CountDownLatch blockerStarted = new CountDownLatch(1);
1934 final List<Future<?>> futures = new ArrayList<>();
1935 for (int i = 0; i < 2; i++) {
1936 Runnable r = new CheckedRunnable() { public void realRun()
1937 throws Throwable {
1938 blockerStarted.countDown();
1939 assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
1940 }};
1941 futures.add(e.submit(r));
1942 }
1943 await(blockerStarted);
1944 for (Future<?> future : futures) future.cancel(false);
1945 for (Future<?> future : futures) {
1946 try {
1947 future.get();
1948 shouldThrow();
1949 } catch (CancellationException success) {}
1950 try {
1951 future.get(LONG_DELAY_MS, MILLISECONDS);
1952 shouldThrow();
1953 } catch (CancellationException success) {}
1954 assertTrue(future.isCancelled());
1955 assertTrue(future.isDone());
1956 }
1957 }
1958 }
1959
1960 /** Directly test simple ThreadPoolExecutor RejectedExecutionHandlers. */
1961 public void testStandardRejectedExecutionHandlers() {
1962 final ThreadPoolExecutor p =
1963 new ThreadPoolExecutor(1, 1, 1, SECONDS,
1964 new ArrayBlockingQueue<Runnable>(1));
1965 final AtomicReference<Thread> thread = new AtomicReference<>();
1966 final Runnable r = new Runnable() { public void run() {
1967 thread.set(Thread.currentThread()); }};
1968
1969 try {
1970 new AbortPolicy().rejectedExecution(r, p);
1971 shouldThrow();
1972 } catch (RejectedExecutionException success) {}
1973 assertNull(thread.get());
1974
1975 new DiscardPolicy().rejectedExecution(r, p);
1976 assertNull(thread.get());
1977
1978 new CallerRunsPolicy().rejectedExecution(r, p);
1979 assertSame(Thread.currentThread(), thread.get());
1980
1981 // check that pool was not perturbed by handlers
1982 assertTrue(p.getRejectedExecutionHandler() instanceof AbortPolicy);
1983 assertEquals(0, p.getTaskCount());
1984 assertTrue(p.getQueue().isEmpty());
1985 }
1986
1987 public void testThreadFactoryReturnsTerminatedThread_shouldThrow() {
1988 if (!testImplementationDetails)
1989 return;
1990
1991 ThreadFactory returnsTerminatedThread = runnableIgnored -> {
1992 Thread thread = new Thread(() -> {});
1993 thread.start();
1994 try { thread.join(); }
1995 catch (InterruptedException ex) { throw new Error(ex); }
1996 return thread;
1997 };
1998 ThreadPoolExecutor p =
1999 new ThreadPoolExecutor(1, 1, 1, SECONDS,
2000 new ArrayBlockingQueue<Runnable>(1),
2001 returnsTerminatedThread);
2002 try (PoolCleaner cleaner = cleaner(p)) {
2003 assertThrows(IllegalThreadStateException.class,
2004 () -> p.execute(() -> {}));
2005 }
2006 }
2007
2008 public void testThreadFactoryReturnsStartedThread_shouldThrow() {
2009 if (!testImplementationDetails)
2010 return;
2011
2012 CountDownLatch latch = new CountDownLatch(1);
2013 Runnable awaitLatch = () -> {
2014 try { latch.await(); }
2015 catch (InterruptedException ex) { throw new Error(ex); }};
2016 ThreadFactory returnsStartedThread = runnable -> {
2017 Thread thread = new Thread(awaitLatch);
2018 thread.start();
2019 return thread;
2020 };
2021 ThreadPoolExecutor p =
2022 new ThreadPoolExecutor(1, 1, 1, SECONDS,
2023 new ArrayBlockingQueue<Runnable>(1),
2024 returnsStartedThread);
2025 try (PoolCleaner cleaner = cleaner(p)) {
2026 assertThrows(IllegalThreadStateException.class,
2027 () -> p.execute(() -> {}));
2028 latch.countDown();
2029 }
2030 }
2031
2032 }