ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.56
Committed: Sun Oct 4 01:30:27 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.55: +7 -3 lines
Log Message:
improve testGetKeepAliveTime

File Contents

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