ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.63
Committed: Sun Oct 4 02:07:32 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.62: +11 -3 lines
Log Message:
improve testGetMaximumPoolSize

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