ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.68
Committed: Sun Oct 4 02:26:47 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.67: +9 -6 lines
Log Message:
improve testIsShutdown

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 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 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 ThreadPoolExecutor p =
549 new CustomTPE(1, 1,
550 LONG_DELAY_MS, MILLISECONDS,
551 new ArrayBlockingQueue<Runnable>(10));
552 try (PoolCleaner cleaner = cleaner(p)) {
553 final CountDownLatch threadStarted = new CountDownLatch(1);
554 final CountDownLatch done = new CountDownLatch(1);
555 assertEquals(0, p.getTaskCount());
556 p.execute(new CheckedRunnable() {
557 public void realRun() throws InterruptedException {
558 threadStarted.countDown();
559 assertEquals(1, p.getTaskCount());
560 done.await();
561 }});
562 assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
563 assertEquals(1, p.getTaskCount());
564 done.countDown();
565 }
566 }
567
568 /**
569 * isShutdown is false before shutdown, true after
570 */
571 public void testIsShutdown() {
572 final ThreadPoolExecutor p =
573 new CustomTPE(1, 1,
574 LONG_DELAY_MS, MILLISECONDS,
575 new ArrayBlockingQueue<Runnable>(10));
576 try (PoolCleaner cleaner = cleaner(p)) {
577 assertFalse(p.isShutdown());
578 try { p.shutdown(); } catch (SecurityException ok) { return; }
579 assertTrue(p.isShutdown());
580 }
581 }
582
583 /**
584 * isTerminated is false before termination, true after
585 */
586 public void testIsTerminated() throws InterruptedException {
587 final ThreadPoolExecutor p =
588 new CustomTPE(1, 1,
589 LONG_DELAY_MS, MILLISECONDS,
590 new ArrayBlockingQueue<Runnable>(10));
591 final CountDownLatch threadStarted = new CountDownLatch(1);
592 final CountDownLatch done = new CountDownLatch(1);
593 try {
594 assertFalse(p.isTerminating());
595 p.execute(new CheckedRunnable() {
596 public void realRun() throws InterruptedException {
597 assertFalse(p.isTerminating());
598 threadStarted.countDown();
599 done.await();
600 }});
601 assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
602 assertFalse(p.isTerminating());
603 done.countDown();
604 } finally {
605 try { p.shutdown(); } catch (SecurityException ok) { return; }
606 }
607 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
608 assertTrue(p.isTerminated());
609 assertFalse(p.isTerminating());
610 }
611
612 /**
613 * isTerminating is not true when running or when terminated
614 */
615 public void testIsTerminating() throws InterruptedException {
616 final ThreadPoolExecutor p =
617 new CustomTPE(1, 1,
618 LONG_DELAY_MS, MILLISECONDS,
619 new ArrayBlockingQueue<Runnable>(10));
620 final CountDownLatch threadStarted = new CountDownLatch(1);
621 final CountDownLatch done = new CountDownLatch(1);
622 try {
623 assertFalse(p.isTerminating());
624 p.execute(new CheckedRunnable() {
625 public void realRun() throws InterruptedException {
626 assertFalse(p.isTerminating());
627 threadStarted.countDown();
628 done.await();
629 }});
630 assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
631 assertFalse(p.isTerminating());
632 done.countDown();
633 } finally {
634 try { p.shutdown(); } catch (SecurityException ok) { return; }
635 }
636 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
637 assertTrue(p.isTerminated());
638 assertFalse(p.isTerminating());
639 }
640
641 /**
642 * getQueue returns the work queue, which contains queued tasks
643 */
644 public void testGetQueue() throws InterruptedException {
645 final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
646 final ThreadPoolExecutor p =
647 new CustomTPE(1, 1,
648 LONG_DELAY_MS, MILLISECONDS,
649 q);
650 final CountDownLatch threadStarted = new CountDownLatch(1);
651 final CountDownLatch done = new CountDownLatch(1);
652 try {
653 FutureTask[] tasks = new FutureTask[5];
654 for (int i = 0; i < tasks.length; i++) {
655 Callable task = new CheckedCallable<Boolean>() {
656 public Boolean realCall() throws InterruptedException {
657 threadStarted.countDown();
658 assertSame(q, p.getQueue());
659 done.await();
660 return Boolean.TRUE;
661 }};
662 tasks[i] = new FutureTask(task);
663 p.execute(tasks[i]);
664 }
665 assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
666 assertSame(q, p.getQueue());
667 assertFalse(q.contains(tasks[0]));
668 assertTrue(q.contains(tasks[tasks.length - 1]));
669 assertEquals(tasks.length - 1, q.size());
670 } finally {
671 done.countDown();
672 joinPool(p);
673 }
674 }
675
676 /**
677 * remove(task) removes queued task, and fails to remove active task
678 */
679 public void testRemove() throws InterruptedException {
680 BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
681 final ThreadPoolExecutor p =
682 new CustomTPE(1, 1,
683 LONG_DELAY_MS, MILLISECONDS,
684 q);
685 Runnable[] tasks = new Runnable[6];
686 final CountDownLatch threadStarted = new CountDownLatch(1);
687 final CountDownLatch done = new CountDownLatch(1);
688 try {
689 for (int i = 0; i < tasks.length; i++) {
690 tasks[i] = new CheckedRunnable() {
691 public void realRun() throws InterruptedException {
692 threadStarted.countDown();
693 done.await();
694 }};
695 p.execute(tasks[i]);
696 }
697 assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
698 assertFalse(p.remove(tasks[0]));
699 assertTrue(q.contains(tasks[4]));
700 assertTrue(q.contains(tasks[3]));
701 assertTrue(p.remove(tasks[4]));
702 assertFalse(p.remove(tasks[4]));
703 assertFalse(q.contains(tasks[4]));
704 assertTrue(q.contains(tasks[3]));
705 assertTrue(p.remove(tasks[3]));
706 assertFalse(q.contains(tasks[3]));
707 } finally {
708 done.countDown();
709 joinPool(p);
710 }
711 }
712
713 /**
714 * purge removes cancelled tasks from the queue
715 */
716 public void testPurge() throws InterruptedException {
717 final CountDownLatch threadStarted = new CountDownLatch(1);
718 final CountDownLatch done = new CountDownLatch(1);
719 final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
720 final ThreadPoolExecutor p =
721 new CustomTPE(1, 1,
722 LONG_DELAY_MS, MILLISECONDS,
723 q);
724 FutureTask[] tasks = new FutureTask[5];
725 try {
726 for (int i = 0; i < tasks.length; i++) {
727 Callable task = new CheckedCallable<Boolean>() {
728 public Boolean realCall() throws InterruptedException {
729 threadStarted.countDown();
730 done.await();
731 return Boolean.TRUE;
732 }};
733 tasks[i] = new FutureTask(task);
734 p.execute(tasks[i]);
735 }
736 assertTrue(threadStarted.await(MEDIUM_DELAY_MS, MILLISECONDS));
737 assertEquals(tasks.length, p.getTaskCount());
738 assertEquals(tasks.length - 1, q.size());
739 assertEquals(1L, p.getActiveCount());
740 assertEquals(0L, p.getCompletedTaskCount());
741 tasks[4].cancel(true);
742 tasks[3].cancel(false);
743 p.purge();
744 assertEquals(tasks.length - 3, q.size());
745 assertEquals(tasks.length - 2, p.getTaskCount());
746 p.purge(); // Nothing to do
747 assertEquals(tasks.length - 3, q.size());
748 assertEquals(tasks.length - 2, p.getTaskCount());
749 } finally {
750 done.countDown();
751 joinPool(p);
752 }
753 }
754
755 /**
756 * shutdownNow returns a list containing tasks that were not run,
757 * and those tasks are drained from the queue
758 */
759 public void testShutdownNow() throws InterruptedException {
760 final int poolSize = 2;
761 final int count = 5;
762 final AtomicInteger ran = new AtomicInteger(0);
763 ThreadPoolExecutor p =
764 new CustomTPE(poolSize, poolSize, LONG_DELAY_MS, MILLISECONDS,
765 new ArrayBlockingQueue<Runnable>(10));
766 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 assertTrue(threadsStarted.await(LONG_DELAY_MS, MILLISECONDS));
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 ThreadPoolExecutor p =
1136 new CustomTPE(1, 1,
1137 LONG_DELAY_MS, MILLISECONDS,
1138 new ArrayBlockingQueue<Runnable>(1));
1139 final CountDownLatch done = new CountDownLatch(1);
1140 try {
1141 Runnable task = new CheckedRunnable() {
1142 public void realRun() throws InterruptedException {
1143 done.await();
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 } finally {
1155 done.countDown();
1156 joinPool(p);
1157 }
1158 }
1159
1160 /**
1161 * executor using CallerRunsPolicy runs task if saturated.
1162 */
1163 public void testSaturatedExecute2() {
1164 RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
1165 ThreadPoolExecutor p = new CustomTPE(1, 1,
1166 LONG_DELAY_MS, MILLISECONDS,
1167 new ArrayBlockingQueue<Runnable>(1),
1168 h);
1169 try {
1170 TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
1171 for (int i = 0; i < tasks.length; ++i)
1172 tasks[i] = new TrackedNoOpRunnable();
1173 TrackedLongRunnable mr = new TrackedLongRunnable();
1174 p.execute(mr);
1175 for (int i = 0; i < tasks.length; ++i)
1176 p.execute(tasks[i]);
1177 for (int i = 1; i < tasks.length; ++i)
1178 assertTrue(tasks[i].done);
1179 try { p.shutdownNow(); } catch (SecurityException ok) { return; }
1180 } finally {
1181 joinPool(p);
1182 }
1183 }
1184
1185 /**
1186 * executor using DiscardPolicy drops task if saturated.
1187 */
1188 public void testSaturatedExecute3() {
1189 RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
1190 ThreadPoolExecutor p =
1191 new CustomTPE(1, 1,
1192 LONG_DELAY_MS, MILLISECONDS,
1193 new ArrayBlockingQueue<Runnable>(1),
1194 h);
1195 try {
1196 TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
1197 for (int i = 0; i < tasks.length; ++i)
1198 tasks[i] = new TrackedNoOpRunnable();
1199 p.execute(new TrackedLongRunnable());
1200 for (TrackedNoOpRunnable task : tasks)
1201 p.execute(task);
1202 for (TrackedNoOpRunnable task : tasks)
1203 assertFalse(task.done);
1204 try { p.shutdownNow(); } catch (SecurityException ok) { return; }
1205 } finally {
1206 joinPool(p);
1207 }
1208 }
1209
1210 /**
1211 * executor using DiscardOldestPolicy drops oldest task if saturated.
1212 */
1213 public void testSaturatedExecute4() {
1214 RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
1215 ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1216 try {
1217 p.execute(new TrackedLongRunnable());
1218 TrackedLongRunnable r2 = new TrackedLongRunnable();
1219 p.execute(r2);
1220 assertTrue(p.getQueue().contains(r2));
1221 TrackedNoOpRunnable r3 = new TrackedNoOpRunnable();
1222 p.execute(r3);
1223 assertFalse(p.getQueue().contains(r2));
1224 assertTrue(p.getQueue().contains(r3));
1225 try { p.shutdownNow(); } catch (SecurityException ok) { return; }
1226 } finally {
1227 joinPool(p);
1228 }
1229 }
1230
1231 /**
1232 * execute throws RejectedExecutionException if shutdown
1233 */
1234 public void testRejectedExecutionExceptionOnShutdown() {
1235 ThreadPoolExecutor p =
1236 new CustomTPE(1,1,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(1));
1237 try { p.shutdown(); } catch (SecurityException ok) { return; }
1238 try {
1239 p.execute(new NoOpRunnable());
1240 shouldThrow();
1241 } catch (RejectedExecutionException success) {}
1242
1243 joinPool(p);
1244 }
1245
1246 /**
1247 * execute using CallerRunsPolicy drops task on shutdown
1248 */
1249 public void testCallerRunsOnShutdown() {
1250 RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
1251 ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1252
1253 try { p.shutdown(); } catch (SecurityException ok) { return; }
1254 try {
1255 TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1256 p.execute(r);
1257 assertFalse(r.done);
1258 } finally {
1259 joinPool(p);
1260 }
1261 }
1262
1263 /**
1264 * execute using DiscardPolicy drops task on shutdown
1265 */
1266 public void testDiscardOnShutdown() {
1267 RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
1268 ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1269
1270 try { p.shutdown(); } catch (SecurityException ok) { return; }
1271 try {
1272 TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1273 p.execute(r);
1274 assertFalse(r.done);
1275 } finally {
1276 joinPool(p);
1277 }
1278 }
1279
1280 /**
1281 * execute using DiscardOldestPolicy drops task on shutdown
1282 */
1283 public void testDiscardOldestOnShutdown() {
1284 RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
1285 ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1286
1287 try { p.shutdown(); } catch (SecurityException ok) { return; }
1288 try {
1289 TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1290 p.execute(r);
1291 assertFalse(r.done);
1292 } finally {
1293 joinPool(p);
1294 }
1295 }
1296
1297 /**
1298 * execute(null) throws NPE
1299 */
1300 public void testExecuteNull() {
1301 ThreadPoolExecutor p =
1302 new CustomTPE(1, 2, 1L, SECONDS,
1303 new ArrayBlockingQueue<Runnable>(10));
1304 try {
1305 p.execute(null);
1306 shouldThrow();
1307 } catch (NullPointerException success) {}
1308
1309 joinPool(p);
1310 }
1311
1312 /**
1313 * setCorePoolSize of negative value throws IllegalArgumentException
1314 */
1315 public void testCorePoolSizeIllegalArgumentException() {
1316 ThreadPoolExecutor p =
1317 new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1318 try {
1319 p.setCorePoolSize(-1);
1320 shouldThrow();
1321 } catch (IllegalArgumentException success) {
1322 } finally {
1323 try { p.shutdown(); } catch (SecurityException ok) { return; }
1324 }
1325 joinPool(p);
1326 }
1327
1328 /**
1329 * setMaximumPoolSize(int) throws IllegalArgumentException
1330 * if given a value less the core pool size
1331 */
1332 public void testMaximumPoolSizeIllegalArgumentException() {
1333 ThreadPoolExecutor p =
1334 new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1335 try {
1336 p.setMaximumPoolSize(1);
1337 shouldThrow();
1338 } catch (IllegalArgumentException success) {
1339 } finally {
1340 try { p.shutdown(); } catch (SecurityException ok) { return; }
1341 }
1342 joinPool(p);
1343 }
1344
1345 /**
1346 * setMaximumPoolSize throws IllegalArgumentException
1347 * if given a negative value
1348 */
1349 public void testMaximumPoolSizeIllegalArgumentException2() {
1350 ThreadPoolExecutor p =
1351 new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1352 try {
1353 p.setMaximumPoolSize(-1);
1354 shouldThrow();
1355 } catch (IllegalArgumentException success) {
1356 } finally {
1357 try { p.shutdown(); } catch (SecurityException ok) { return; }
1358 }
1359 joinPool(p);
1360 }
1361
1362 /**
1363 * setKeepAliveTime throws IllegalArgumentException
1364 * when given a negative value
1365 */
1366 public void testKeepAliveTimeIllegalArgumentException() {
1367 ThreadPoolExecutor p =
1368 new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1369
1370 try {
1371 p.setKeepAliveTime(-1,MILLISECONDS);
1372 shouldThrow();
1373 } catch (IllegalArgumentException success) {
1374 } finally {
1375 try { p.shutdown(); } catch (SecurityException ok) { return; }
1376 }
1377 joinPool(p);
1378 }
1379
1380 /**
1381 * terminated() is called on termination
1382 */
1383 public void testTerminated() {
1384 CustomTPE p = new CustomTPE();
1385 try { p.shutdown(); } catch (SecurityException ok) { return; }
1386 assertTrue(p.terminatedCalled());
1387 joinPool(p);
1388 }
1389
1390 /**
1391 * beforeExecute and afterExecute are called when executing task
1392 */
1393 public void testBeforeAfter() throws InterruptedException {
1394 CustomTPE p = new CustomTPE();
1395 try {
1396 final CountDownLatch done = new CountDownLatch(1);
1397 p.execute(new CheckedRunnable() {
1398 public void realRun() {
1399 done.countDown();
1400 }});
1401 await(p.afterCalled);
1402 assertEquals(0, done.getCount());
1403 assertTrue(p.afterCalled());
1404 assertTrue(p.beforeCalled());
1405 try { p.shutdown(); } catch (SecurityException ok) { return; }
1406 } finally {
1407 joinPool(p);
1408 }
1409 }
1410
1411 /**
1412 * completed submit of callable returns result
1413 */
1414 public void testSubmitCallable() throws Exception {
1415 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1416 try {
1417 Future<String> future = e.submit(new StringTask());
1418 String result = future.get();
1419 assertSame(TEST_STRING, result);
1420 } finally {
1421 joinPool(e);
1422 }
1423 }
1424
1425 /**
1426 * completed submit of runnable returns successfully
1427 */
1428 public void testSubmitRunnable() throws Exception {
1429 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1430 try {
1431 Future<?> future = e.submit(new NoOpRunnable());
1432 future.get();
1433 assertTrue(future.isDone());
1434 } finally {
1435 joinPool(e);
1436 }
1437 }
1438
1439 /**
1440 * completed submit of (runnable, result) returns result
1441 */
1442 public void testSubmitRunnable2() throws Exception {
1443 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1444 try {
1445 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
1446 String result = future.get();
1447 assertSame(TEST_STRING, result);
1448 } finally {
1449 joinPool(e);
1450 }
1451 }
1452
1453 /**
1454 * invokeAny(null) throws NPE
1455 */
1456 public void testInvokeAny1() throws Exception {
1457 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1458 try {
1459 e.invokeAny(null);
1460 shouldThrow();
1461 } catch (NullPointerException success) {
1462 } finally {
1463 joinPool(e);
1464 }
1465 }
1466
1467 /**
1468 * invokeAny(empty collection) throws IAE
1469 */
1470 public void testInvokeAny2() throws Exception {
1471 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1472 try {
1473 e.invokeAny(new ArrayList<Callable<String>>());
1474 shouldThrow();
1475 } catch (IllegalArgumentException success) {
1476 } finally {
1477 joinPool(e);
1478 }
1479 }
1480
1481 /**
1482 * invokeAny(c) throws NPE if c has null elements
1483 */
1484 public void testInvokeAny3() throws Exception {
1485 CountDownLatch latch = new CountDownLatch(1);
1486 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1487 List<Callable<String>> l = new ArrayList<Callable<String>>();
1488 l.add(latchAwaitingStringTask(latch));
1489 l.add(null);
1490 try {
1491 e.invokeAny(l);
1492 shouldThrow();
1493 } catch (NullPointerException success) {
1494 } finally {
1495 latch.countDown();
1496 joinPool(e);
1497 }
1498 }
1499
1500 /**
1501 * invokeAny(c) throws ExecutionException if no task completes
1502 */
1503 public void testInvokeAny4() throws Exception {
1504 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1505 List<Callable<String>> l = new ArrayList<Callable<String>>();
1506 l.add(new NPETask());
1507 try {
1508 e.invokeAny(l);
1509 shouldThrow();
1510 } catch (ExecutionException success) {
1511 assertTrue(success.getCause() instanceof NullPointerException);
1512 } finally {
1513 joinPool(e);
1514 }
1515 }
1516
1517 /**
1518 * invokeAny(c) returns result of some task
1519 */
1520 public void testInvokeAny5() throws Exception {
1521 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1522 try {
1523 List<Callable<String>> l = new ArrayList<Callable<String>>();
1524 l.add(new StringTask());
1525 l.add(new StringTask());
1526 String result = e.invokeAny(l);
1527 assertSame(TEST_STRING, result);
1528 } finally {
1529 joinPool(e);
1530 }
1531 }
1532
1533 /**
1534 * invokeAll(null) throws NPE
1535 */
1536 public void testInvokeAll1() throws Exception {
1537 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1538 try {
1539 e.invokeAll(null);
1540 shouldThrow();
1541 } catch (NullPointerException success) {
1542 } finally {
1543 joinPool(e);
1544 }
1545 }
1546
1547 /**
1548 * invokeAll(empty collection) returns empty collection
1549 */
1550 public void testInvokeAll2() throws Exception {
1551 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1552 try {
1553 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
1554 assertTrue(r.isEmpty());
1555 } finally {
1556 joinPool(e);
1557 }
1558 }
1559
1560 /**
1561 * invokeAll(c) throws NPE if c has null elements
1562 */
1563 public void testInvokeAll3() throws Exception {
1564 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1565 List<Callable<String>> l = new ArrayList<Callable<String>>();
1566 l.add(new StringTask());
1567 l.add(null);
1568 try {
1569 e.invokeAll(l);
1570 shouldThrow();
1571 } catch (NullPointerException success) {
1572 } finally {
1573 joinPool(e);
1574 }
1575 }
1576
1577 /**
1578 * get of element of invokeAll(c) throws exception on failed task
1579 */
1580 public void testInvokeAll4() throws Exception {
1581 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1582 List<Callable<String>> l = new ArrayList<Callable<String>>();
1583 l.add(new NPETask());
1584 List<Future<String>> futures = e.invokeAll(l);
1585 assertEquals(1, futures.size());
1586 try {
1587 futures.get(0).get();
1588 shouldThrow();
1589 } catch (ExecutionException success) {
1590 assertTrue(success.getCause() instanceof NullPointerException);
1591 } finally {
1592 joinPool(e);
1593 }
1594 }
1595
1596 /**
1597 * invokeAll(c) returns results of all completed tasks
1598 */
1599 public void testInvokeAll5() throws Exception {
1600 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1601 try {
1602 List<Callable<String>> l = new ArrayList<Callable<String>>();
1603 l.add(new StringTask());
1604 l.add(new StringTask());
1605 List<Future<String>> futures = e.invokeAll(l);
1606 assertEquals(2, futures.size());
1607 for (Future<String> future : futures)
1608 assertSame(TEST_STRING, future.get());
1609 } finally {
1610 joinPool(e);
1611 }
1612 }
1613
1614 /**
1615 * timed invokeAny(null) throws NPE
1616 */
1617 public void testTimedInvokeAny1() throws Exception {
1618 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1619 try {
1620 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
1621 shouldThrow();
1622 } catch (NullPointerException success) {
1623 } finally {
1624 joinPool(e);
1625 }
1626 }
1627
1628 /**
1629 * timed invokeAny(,,null) throws NPE
1630 */
1631 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
1632 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1633 List<Callable<String>> l = new ArrayList<Callable<String>>();
1634 l.add(new StringTask());
1635 try {
1636 e.invokeAny(l, MEDIUM_DELAY_MS, null);
1637 shouldThrow();
1638 } catch (NullPointerException success) {
1639 } finally {
1640 joinPool(e);
1641 }
1642 }
1643
1644 /**
1645 * timed invokeAny(empty collection) throws IAE
1646 */
1647 public void testTimedInvokeAny2() throws Exception {
1648 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1649 try {
1650 e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1651 shouldThrow();
1652 } catch (IllegalArgumentException success) {
1653 } finally {
1654 joinPool(e);
1655 }
1656 }
1657
1658 /**
1659 * timed invokeAny(c) throws NPE if c has null elements
1660 */
1661 public void testTimedInvokeAny3() throws Exception {
1662 CountDownLatch latch = new CountDownLatch(1);
1663 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1664 List<Callable<String>> l = new ArrayList<Callable<String>>();
1665 l.add(latchAwaitingStringTask(latch));
1666 l.add(null);
1667 try {
1668 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1669 shouldThrow();
1670 } catch (NullPointerException success) {
1671 } finally {
1672 latch.countDown();
1673 joinPool(e);
1674 }
1675 }
1676
1677 /**
1678 * timed invokeAny(c) throws ExecutionException if no task completes
1679 */
1680 public void testTimedInvokeAny4() throws Exception {
1681 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1682 List<Callable<String>> l = new ArrayList<Callable<String>>();
1683 l.add(new NPETask());
1684 try {
1685 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1686 shouldThrow();
1687 } catch (ExecutionException success) {
1688 assertTrue(success.getCause() instanceof NullPointerException);
1689 } finally {
1690 joinPool(e);
1691 }
1692 }
1693
1694 /**
1695 * timed invokeAny(c) returns result of some task
1696 */
1697 public void testTimedInvokeAny5() throws Exception {
1698 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1699 try {
1700 List<Callable<String>> l = new ArrayList<Callable<String>>();
1701 l.add(new StringTask());
1702 l.add(new StringTask());
1703 String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1704 assertSame(TEST_STRING, result);
1705 } finally {
1706 joinPool(e);
1707 }
1708 }
1709
1710 /**
1711 * timed invokeAll(null) throws NPE
1712 */
1713 public void testTimedInvokeAll1() throws Exception {
1714 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1715 try {
1716 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
1717 shouldThrow();
1718 } catch (NullPointerException success) {
1719 } finally {
1720 joinPool(e);
1721 }
1722 }
1723
1724 /**
1725 * timed invokeAll(,,null) throws NPE
1726 */
1727 public void testTimedInvokeAllNullTimeUnit() throws Exception {
1728 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1729 List<Callable<String>> l = new ArrayList<Callable<String>>();
1730 l.add(new StringTask());
1731 try {
1732 e.invokeAll(l, MEDIUM_DELAY_MS, null);
1733 shouldThrow();
1734 } catch (NullPointerException success) {
1735 } finally {
1736 joinPool(e);
1737 }
1738 }
1739
1740 /**
1741 * timed invokeAll(empty collection) returns empty collection
1742 */
1743 public void testTimedInvokeAll2() throws Exception {
1744 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1745 try {
1746 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1747 assertTrue(r.isEmpty());
1748 } finally {
1749 joinPool(e);
1750 }
1751 }
1752
1753 /**
1754 * timed invokeAll(c) throws NPE if c has null elements
1755 */
1756 public void testTimedInvokeAll3() throws Exception {
1757 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1758 List<Callable<String>> l = new ArrayList<Callable<String>>();
1759 l.add(new StringTask());
1760 l.add(null);
1761 try {
1762 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1763 shouldThrow();
1764 } catch (NullPointerException success) {
1765 } finally {
1766 joinPool(e);
1767 }
1768 }
1769
1770 /**
1771 * get of element of invokeAll(c) throws exception on failed task
1772 */
1773 public void testTimedInvokeAll4() throws Exception {
1774 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1775 List<Callable<String>> l = new ArrayList<Callable<String>>();
1776 l.add(new NPETask());
1777 List<Future<String>> futures =
1778 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1779 assertEquals(1, futures.size());
1780 try {
1781 futures.get(0).get();
1782 shouldThrow();
1783 } catch (ExecutionException success) {
1784 assertTrue(success.getCause() instanceof NullPointerException);
1785 } finally {
1786 joinPool(e);
1787 }
1788 }
1789
1790 /**
1791 * timed invokeAll(c) returns results of all completed tasks
1792 */
1793 public void testTimedInvokeAll5() throws Exception {
1794 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1795 try {
1796 List<Callable<String>> l = new ArrayList<Callable<String>>();
1797 l.add(new StringTask());
1798 l.add(new StringTask());
1799 List<Future<String>> futures =
1800 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1801 assertEquals(2, futures.size());
1802 for (Future<String> future : futures)
1803 assertSame(TEST_STRING, future.get());
1804 } finally {
1805 joinPool(e);
1806 }
1807 }
1808
1809 /**
1810 * timed invokeAll(c) cancels tasks not completed by timeout
1811 */
1812 public void testTimedInvokeAll6() throws Exception {
1813 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1814 try {
1815 for (long timeout = timeoutMillis();;) {
1816 List<Callable<String>> tasks = new ArrayList<>();
1817 tasks.add(new StringTask("0"));
1818 tasks.add(Executors.callable(new LongPossiblyInterruptedRunnable(), TEST_STRING));
1819 tasks.add(new StringTask("2"));
1820 long startTime = System.nanoTime();
1821 List<Future<String>> futures =
1822 e.invokeAll(tasks, timeout, MILLISECONDS);
1823 assertEquals(tasks.size(), futures.size());
1824 assertTrue(millisElapsedSince(startTime) >= timeout);
1825 for (Future future : futures)
1826 assertTrue(future.isDone());
1827 assertTrue(futures.get(1).isCancelled());
1828 try {
1829 assertEquals("0", futures.get(0).get());
1830 assertEquals("2", futures.get(2).get());
1831 break;
1832 } catch (CancellationException retryWithLongerTimeout) {
1833 timeout *= 2;
1834 if (timeout >= LONG_DELAY_MS / 2)
1835 fail("expected exactly one task to be cancelled");
1836 }
1837 }
1838 } finally {
1839 joinPool(e);
1840 }
1841 }
1842
1843 /**
1844 * Execution continues if there is at least one thread even if
1845 * thread factory fails to create more
1846 */
1847 public void testFailingThreadFactory() throws InterruptedException {
1848 final ExecutorService e =
1849 new CustomTPE(100, 100,
1850 LONG_DELAY_MS, MILLISECONDS,
1851 new LinkedBlockingQueue<Runnable>(),
1852 new FailingThreadFactory());
1853 try {
1854 final int TASKS = 100;
1855 final CountDownLatch done = new CountDownLatch(TASKS);
1856 for (int k = 0; k < TASKS; ++k)
1857 e.execute(new CheckedRunnable() {
1858 public void realRun() {
1859 done.countDown();
1860 }});
1861 assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
1862 } finally {
1863 joinPool(e);
1864 }
1865 }
1866
1867 /**
1868 * allowsCoreThreadTimeOut is by default false.
1869 */
1870 public void testAllowsCoreThreadTimeOut() {
1871 ThreadPoolExecutor p = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1872 assertFalse(p.allowsCoreThreadTimeOut());
1873 joinPool(p);
1874 }
1875
1876 /**
1877 * allowCoreThreadTimeOut(true) causes idle threads to time out
1878 */
1879 public void testAllowCoreThreadTimeOut_true() throws Exception {
1880 long keepAliveTime = timeoutMillis();
1881 final ThreadPoolExecutor p =
1882 new CustomTPE(2, 10,
1883 keepAliveTime, MILLISECONDS,
1884 new ArrayBlockingQueue<Runnable>(10));
1885 final CountDownLatch threadStarted = new CountDownLatch(1);
1886 try {
1887 p.allowCoreThreadTimeOut(true);
1888 p.execute(new CheckedRunnable() {
1889 public void realRun() {
1890 threadStarted.countDown();
1891 assertEquals(1, p.getPoolSize());
1892 }});
1893 await(threadStarted);
1894 delay(keepAliveTime);
1895 long startTime = System.nanoTime();
1896 while (p.getPoolSize() > 0
1897 && millisElapsedSince(startTime) < LONG_DELAY_MS)
1898 Thread.yield();
1899 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1900 assertEquals(0, p.getPoolSize());
1901 } finally {
1902 joinPool(p);
1903 }
1904 }
1905
1906 /**
1907 * allowCoreThreadTimeOut(false) causes idle threads not to time out
1908 */
1909 public void testAllowCoreThreadTimeOut_false() throws Exception {
1910 long keepAliveTime = timeoutMillis();
1911 final ThreadPoolExecutor p =
1912 new CustomTPE(2, 10,
1913 keepAliveTime, MILLISECONDS,
1914 new ArrayBlockingQueue<Runnable>(10));
1915 final CountDownLatch threadStarted = new CountDownLatch(1);
1916 try {
1917 p.allowCoreThreadTimeOut(false);
1918 p.execute(new CheckedRunnable() {
1919 public void realRun() throws InterruptedException {
1920 threadStarted.countDown();
1921 assertTrue(p.getPoolSize() >= 1);
1922 }});
1923 delay(2 * keepAliveTime);
1924 assertTrue(p.getPoolSize() >= 1);
1925 } finally {
1926 joinPool(p);
1927 }
1928 }
1929
1930 /**
1931 * get(cancelled task) throws CancellationException
1932 * (in part, a test of CustomTPE itself)
1933 */
1934 public void testGet_cancelled() throws Exception {
1935 final ExecutorService e =
1936 new CustomTPE(1, 1,
1937 LONG_DELAY_MS, MILLISECONDS,
1938 new LinkedBlockingQueue<Runnable>());
1939 try {
1940 final CountDownLatch blockerStarted = new CountDownLatch(1);
1941 final CountDownLatch done = new CountDownLatch(1);
1942 final List<Future<?>> futures = new ArrayList<>();
1943 for (int i = 0; i < 2; i++) {
1944 Runnable r = new CheckedRunnable() { public void realRun()
1945 throws Throwable {
1946 blockerStarted.countDown();
1947 assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
1948 }};
1949 futures.add(e.submit(r));
1950 }
1951 assertTrue(blockerStarted.await(LONG_DELAY_MS, MILLISECONDS));
1952 for (Future<?> future : futures) future.cancel(false);
1953 for (Future<?> future : futures) {
1954 try {
1955 future.get();
1956 shouldThrow();
1957 } catch (CancellationException success) {}
1958 try {
1959 future.get(LONG_DELAY_MS, MILLISECONDS);
1960 shouldThrow();
1961 } catch (CancellationException success) {}
1962 assertTrue(future.isCancelled());
1963 assertTrue(future.isDone());
1964 }
1965 done.countDown();
1966 } finally {
1967 joinPool(e);
1968 }
1969 }
1970
1971 }