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