ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.84
Committed: Mon Oct 5 21:42:48 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.83: +19 -5 lines
Log Message:
improve testGetTaskCount

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