ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.39
Committed: Mon Sep 14 03:27:11 2015 UTC (8 years, 8 months ago) by jsr166
Branch: MAIN
Changes since 1.38: +31 -18 lines
Log Message:
improve testTimedInvokeAll6

File Contents

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