ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.97
Committed: Wed Jan 4 06:09:58 2017 UTC (7 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.96: +19 -19 lines
Log Message:
convert to Diamond

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