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