ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.36
Committed: Fri May 15 17:07:27 2015 UTC (9 years ago) by jsr166
Branch: MAIN
Changes since 1.35: +81 -32 lines
Log Message:
make constructor tests more readable

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