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

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 threadFactory = new SimpleThreadFactory();
384 ThreadPoolExecutor p =
385 new CustomTPE(1, 2,
386 LONG_DELAY_MS, MILLISECONDS,
387 new ArrayBlockingQueue<Runnable>(10),
388 threadFactory,
389 new NoOpREHandler());
390 try (PoolCleaner cleaner = cleaner(p)) {
391 assertSame(threadFactory, p.getThreadFactory());
392 }
393 }
394
395 /**
396 * setThreadFactory sets the thread factory returned by getThreadFactory
397 */
398 public void testSetThreadFactory() {
399 ThreadPoolExecutor p =
400 new CustomTPE(1, 2,
401 LONG_DELAY_MS, MILLISECONDS,
402 new ArrayBlockingQueue<Runnable>(10));
403 try (PoolCleaner cleaner = cleaner(p)) {
404 ThreadFactory threadFactory = new SimpleThreadFactory();
405 p.setThreadFactory(threadFactory);
406 assertSame(threadFactory, p.getThreadFactory());
407 }
408 }
409
410 /**
411 * setThreadFactory(null) throws NPE
412 */
413 public void testSetThreadFactoryNull() {
414 ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
415 try {
416 p.setThreadFactory(null);
417 shouldThrow();
418 } catch (NullPointerException success) {
419 } finally {
420 joinPool(p);
421 }
422 }
423
424 /**
425 * getRejectedExecutionHandler returns handler in constructor if not set
426 */
427 public void testGetRejectedExecutionHandler() {
428 RejectedExecutionHandler h = new NoOpREHandler();
429 ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10), h);
430 assertSame(h, p.getRejectedExecutionHandler());
431 joinPool(p);
432 }
433
434 /**
435 * setRejectedExecutionHandler sets the handler returned by
436 * getRejectedExecutionHandler
437 */
438 public void testSetRejectedExecutionHandler() {
439 ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
440 RejectedExecutionHandler h = new NoOpREHandler();
441 p.setRejectedExecutionHandler(h);
442 assertSame(h, p.getRejectedExecutionHandler());
443 joinPool(p);
444 }
445
446 /**
447 * setRejectedExecutionHandler(null) throws NPE
448 */
449 public void testSetRejectedExecutionHandlerNull() {
450 ThreadPoolExecutor p = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
451 try {
452 p.setRejectedExecutionHandler(null);
453 shouldThrow();
454 } catch (NullPointerException success) {
455 } finally {
456 joinPool(p);
457 }
458 }
459
460 /**
461 * getLargestPoolSize increases, but doesn't overestimate, when
462 * multiple threads active
463 */
464 public void testGetLargestPoolSize() throws InterruptedException {
465 final int THREADS = 3;
466 final ThreadPoolExecutor p =
467 new CustomTPE(THREADS, THREADS,
468 LONG_DELAY_MS, MILLISECONDS,
469 new ArrayBlockingQueue<Runnable>(10));
470 final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
471 final CountDownLatch done = new CountDownLatch(1);
472 try {
473 assertEquals(0, p.getLargestPoolSize());
474 for (int i = 0; i < THREADS; i++)
475 p.execute(new CheckedRunnable() {
476 public void realRun() throws InterruptedException {
477 threadsStarted.countDown();
478 done.await();
479 assertEquals(THREADS, p.getLargestPoolSize());
480 }});
481 assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
482 assertEquals(THREADS, p.getLargestPoolSize());
483 } finally {
484 done.countDown();
485 joinPool(p);
486 assertEquals(THREADS, p.getLargestPoolSize());
487 }
488 }
489
490 /**
491 * getMaximumPoolSize returns value given in constructor if not
492 * otherwise set
493 */
494 public void testGetMaximumPoolSize() {
495 ThreadPoolExecutor p = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
496 assertEquals(2, p.getMaximumPoolSize());
497 joinPool(p);
498 }
499
500 /**
501 * getPoolSize increases, but doesn't overestimate, when threads
502 * become active
503 */
504 public void testGetPoolSize() throws InterruptedException {
505 final ThreadPoolExecutor p =
506 new CustomTPE(1, 1,
507 LONG_DELAY_MS, MILLISECONDS,
508 new ArrayBlockingQueue<Runnable>(10));
509 final CountDownLatch threadStarted = new CountDownLatch(1);
510 final CountDownLatch done = new CountDownLatch(1);
511 try {
512 assertEquals(0, p.getPoolSize());
513 p.execute(new CheckedRunnable() {
514 public void realRun() throws InterruptedException {
515 threadStarted.countDown();
516 assertEquals(1, p.getPoolSize());
517 done.await();
518 }});
519 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
520 assertEquals(1, p.getPoolSize());
521 } finally {
522 done.countDown();
523 joinPool(p);
524 }
525 }
526
527 /**
528 * getTaskCount increases, but doesn't overestimate, when tasks submitted
529 */
530 public void testGetTaskCount() throws InterruptedException {
531 final ThreadPoolExecutor p =
532 new CustomTPE(1, 1,
533 LONG_DELAY_MS, MILLISECONDS,
534 new ArrayBlockingQueue<Runnable>(10));
535 final CountDownLatch threadStarted = new CountDownLatch(1);
536 final CountDownLatch done = new CountDownLatch(1);
537 try {
538 assertEquals(0, p.getTaskCount());
539 p.execute(new CheckedRunnable() {
540 public void realRun() throws InterruptedException {
541 threadStarted.countDown();
542 assertEquals(1, p.getTaskCount());
543 done.await();
544 }});
545 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
546 assertEquals(1, p.getTaskCount());
547 } finally {
548 done.countDown();
549 joinPool(p);
550 }
551 }
552
553 /**
554 * isShutdown is false before shutdown, true after
555 */
556 public void testIsShutdown() {
557
558 ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
559 assertFalse(p.isShutdown());
560 try { p.shutdown(); } catch (SecurityException ok) { return; }
561 assertTrue(p.isShutdown());
562 joinPool(p);
563 }
564
565 /**
566 * isTerminated is false before termination, true after
567 */
568 public void testIsTerminated() throws InterruptedException {
569 final ThreadPoolExecutor p =
570 new CustomTPE(1, 1,
571 LONG_DELAY_MS, MILLISECONDS,
572 new ArrayBlockingQueue<Runnable>(10));
573 final CountDownLatch threadStarted = new CountDownLatch(1);
574 final CountDownLatch done = new CountDownLatch(1);
575 try {
576 assertFalse(p.isTerminating());
577 p.execute(new CheckedRunnable() {
578 public void realRun() throws InterruptedException {
579 assertFalse(p.isTerminating());
580 threadStarted.countDown();
581 done.await();
582 }});
583 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
584 assertFalse(p.isTerminating());
585 done.countDown();
586 } finally {
587 try { p.shutdown(); } catch (SecurityException ok) { return; }
588 }
589 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
590 assertTrue(p.isTerminated());
591 assertFalse(p.isTerminating());
592 }
593
594 /**
595 * isTerminating is not true when running or when terminated
596 */
597 public void testIsTerminating() throws InterruptedException {
598 final ThreadPoolExecutor p =
599 new CustomTPE(1, 1,
600 LONG_DELAY_MS, MILLISECONDS,
601 new ArrayBlockingQueue<Runnable>(10));
602 final CountDownLatch threadStarted = new CountDownLatch(1);
603 final CountDownLatch done = new CountDownLatch(1);
604 try {
605 assertFalse(p.isTerminating());
606 p.execute(new CheckedRunnable() {
607 public void realRun() throws InterruptedException {
608 assertFalse(p.isTerminating());
609 threadStarted.countDown();
610 done.await();
611 }});
612 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
613 assertFalse(p.isTerminating());
614 done.countDown();
615 } finally {
616 try { p.shutdown(); } catch (SecurityException ok) { return; }
617 }
618 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
619 assertTrue(p.isTerminated());
620 assertFalse(p.isTerminating());
621 }
622
623 /**
624 * getQueue returns the work queue, which contains queued tasks
625 */
626 public void testGetQueue() throws InterruptedException {
627 final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
628 final ThreadPoolExecutor p =
629 new CustomTPE(1, 1,
630 LONG_DELAY_MS, MILLISECONDS,
631 q);
632 final CountDownLatch threadStarted = new CountDownLatch(1);
633 final CountDownLatch done = new CountDownLatch(1);
634 try {
635 FutureTask[] tasks = new FutureTask[5];
636 for (int i = 0; i < tasks.length; i++) {
637 Callable task = new CheckedCallable<Boolean>() {
638 public Boolean realCall() throws InterruptedException {
639 threadStarted.countDown();
640 assertSame(q, p.getQueue());
641 done.await();
642 return Boolean.TRUE;
643 }};
644 tasks[i] = new FutureTask(task);
645 p.execute(tasks[i]);
646 }
647 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
648 assertSame(q, p.getQueue());
649 assertFalse(q.contains(tasks[0]));
650 assertTrue(q.contains(tasks[tasks.length - 1]));
651 assertEquals(tasks.length - 1, q.size());
652 } finally {
653 done.countDown();
654 joinPool(p);
655 }
656 }
657
658 /**
659 * remove(task) removes queued task, and fails to remove active task
660 */
661 public void testRemove() throws InterruptedException {
662 BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
663 final ThreadPoolExecutor p =
664 new CustomTPE(1, 1,
665 LONG_DELAY_MS, MILLISECONDS,
666 q);
667 Runnable[] tasks = new Runnable[6];
668 final CountDownLatch threadStarted = new CountDownLatch(1);
669 final CountDownLatch done = new CountDownLatch(1);
670 try {
671 for (int i = 0; i < tasks.length; i++) {
672 tasks[i] = new CheckedRunnable() {
673 public void realRun() throws InterruptedException {
674 threadStarted.countDown();
675 done.await();
676 }};
677 p.execute(tasks[i]);
678 }
679 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
680 assertFalse(p.remove(tasks[0]));
681 assertTrue(q.contains(tasks[4]));
682 assertTrue(q.contains(tasks[3]));
683 assertTrue(p.remove(tasks[4]));
684 assertFalse(p.remove(tasks[4]));
685 assertFalse(q.contains(tasks[4]));
686 assertTrue(q.contains(tasks[3]));
687 assertTrue(p.remove(tasks[3]));
688 assertFalse(q.contains(tasks[3]));
689 } finally {
690 done.countDown();
691 joinPool(p);
692 }
693 }
694
695 /**
696 * purge removes cancelled tasks from the queue
697 */
698 public void testPurge() throws InterruptedException {
699 final CountDownLatch threadStarted = new CountDownLatch(1);
700 final CountDownLatch done = new CountDownLatch(1);
701 final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
702 final ThreadPoolExecutor p =
703 new CustomTPE(1, 1,
704 LONG_DELAY_MS, MILLISECONDS,
705 q);
706 FutureTask[] tasks = new FutureTask[5];
707 try {
708 for (int i = 0; i < tasks.length; i++) {
709 Callable task = new CheckedCallable<Boolean>() {
710 public Boolean realCall() throws InterruptedException {
711 threadStarted.countDown();
712 done.await();
713 return Boolean.TRUE;
714 }};
715 tasks[i] = new FutureTask(task);
716 p.execute(tasks[i]);
717 }
718 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
719 assertEquals(tasks.length, p.getTaskCount());
720 assertEquals(tasks.length - 1, q.size());
721 assertEquals(1L, p.getActiveCount());
722 assertEquals(0L, p.getCompletedTaskCount());
723 tasks[4].cancel(true);
724 tasks[3].cancel(false);
725 p.purge();
726 assertEquals(tasks.length - 3, q.size());
727 assertEquals(tasks.length - 2, p.getTaskCount());
728 p.purge(); // Nothing to do
729 assertEquals(tasks.length - 3, q.size());
730 assertEquals(tasks.length - 2, p.getTaskCount());
731 } finally {
732 done.countDown();
733 joinPool(p);
734 }
735 }
736
737 /**
738 * shutdownNow returns a list containing tasks that were not run,
739 * and those tasks are drained from the queue
740 */
741 public void testShutdownNow() throws InterruptedException {
742 final int poolSize = 2;
743 final int count = 5;
744 final AtomicInteger ran = new AtomicInteger(0);
745 ThreadPoolExecutor p =
746 new CustomTPE(poolSize, poolSize, LONG_DELAY_MS, MILLISECONDS,
747 new ArrayBlockingQueue<Runnable>(10));
748 CountDownLatch threadsStarted = new CountDownLatch(poolSize);
749 Runnable waiter = new CheckedRunnable() { public void realRun() {
750 threadsStarted.countDown();
751 try {
752 MILLISECONDS.sleep(2 * LONG_DELAY_MS);
753 } catch (InterruptedException success) {}
754 ran.getAndIncrement();
755 }};
756 for (int i = 0; i < count; i++)
757 p.execute(waiter);
758 assertTrue(threadsStarted.await(LONG_DELAY_MS, MILLISECONDS));
759 assertEquals(poolSize, p.getActiveCount());
760 assertEquals(0, p.getCompletedTaskCount());
761 final List<Runnable> queuedTasks;
762 try {
763 queuedTasks = p.shutdownNow();
764 } catch (SecurityException ok) {
765 return; // Allowed in case test doesn't have privs
766 }
767 assertTrue(p.isShutdown());
768 assertTrue(p.getQueue().isEmpty());
769 assertEquals(count - poolSize, queuedTasks.size());
770 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
771 assertTrue(p.isTerminated());
772 assertEquals(poolSize, ran.get());
773 assertEquals(poolSize, p.getCompletedTaskCount());
774 }
775
776 // Exception Tests
777
778 /**
779 * Constructor throws if corePoolSize argument is less than zero
780 */
781 public void testConstructor1() {
782 try {
783 new CustomTPE(-1, 1, 1L, SECONDS,
784 new ArrayBlockingQueue<Runnable>(10));
785 shouldThrow();
786 } catch (IllegalArgumentException success) {}
787 }
788
789 /**
790 * Constructor throws if maximumPoolSize is less than zero
791 */
792 public void testConstructor2() {
793 try {
794 new CustomTPE(1, -1, 1L, SECONDS,
795 new ArrayBlockingQueue<Runnable>(10));
796 shouldThrow();
797 } catch (IllegalArgumentException success) {}
798 }
799
800 /**
801 * Constructor throws if maximumPoolSize is equal to zero
802 */
803 public void testConstructor3() {
804 try {
805 new CustomTPE(1, 0, 1L, SECONDS,
806 new ArrayBlockingQueue<Runnable>(10));
807 shouldThrow();
808 } catch (IllegalArgumentException success) {}
809 }
810
811 /**
812 * Constructor throws if keepAliveTime is less than zero
813 */
814 public void testConstructor4() {
815 try {
816 new CustomTPE(1, 2, -1L, SECONDS,
817 new ArrayBlockingQueue<Runnable>(10));
818 shouldThrow();
819 } catch (IllegalArgumentException success) {}
820 }
821
822 /**
823 * Constructor throws if corePoolSize is greater than the maximumPoolSize
824 */
825 public void testConstructor5() {
826 try {
827 new CustomTPE(2, 1, 1L, SECONDS,
828 new ArrayBlockingQueue<Runnable>(10));
829 shouldThrow();
830 } catch (IllegalArgumentException success) {}
831 }
832
833 /**
834 * Constructor throws if workQueue is set to null
835 */
836 public void testConstructorNullPointerException() {
837 try {
838 new CustomTPE(1, 2, 1L, SECONDS, null);
839 shouldThrow();
840 } catch (NullPointerException success) {}
841 }
842
843 /**
844 * Constructor throws if corePoolSize argument is less than zero
845 */
846 public void testConstructor6() {
847 try {
848 new CustomTPE(-1, 1, 1L, SECONDS,
849 new ArrayBlockingQueue<Runnable>(10),
850 new SimpleThreadFactory());
851 shouldThrow();
852 } catch (IllegalArgumentException success) {}
853 }
854
855 /**
856 * Constructor throws if maximumPoolSize is less than zero
857 */
858 public void testConstructor7() {
859 try {
860 new CustomTPE(1,-1, 1L, SECONDS,
861 new ArrayBlockingQueue<Runnable>(10),
862 new SimpleThreadFactory());
863 shouldThrow();
864 } catch (IllegalArgumentException success) {}
865 }
866
867 /**
868 * Constructor throws if maximumPoolSize is equal to zero
869 */
870 public void testConstructor8() {
871 try {
872 new CustomTPE(1, 0, 1L, SECONDS,
873 new ArrayBlockingQueue<Runnable>(10),
874 new SimpleThreadFactory());
875 shouldThrow();
876 } catch (IllegalArgumentException success) {}
877 }
878
879 /**
880 * Constructor throws if keepAliveTime is less than zero
881 */
882 public void testConstructor9() {
883 try {
884 new CustomTPE(1, 2, -1L, SECONDS,
885 new ArrayBlockingQueue<Runnable>(10),
886 new SimpleThreadFactory());
887 shouldThrow();
888 } catch (IllegalArgumentException success) {}
889 }
890
891 /**
892 * Constructor throws if corePoolSize is greater than the maximumPoolSize
893 */
894 public void testConstructor10() {
895 try {
896 new CustomTPE(2, 1, 1L, SECONDS,
897 new ArrayBlockingQueue<Runnable>(10),
898 new SimpleThreadFactory());
899 shouldThrow();
900 } catch (IllegalArgumentException success) {}
901 }
902
903 /**
904 * Constructor throws if workQueue is set to null
905 */
906 public void testConstructorNullPointerException2() {
907 try {
908 new CustomTPE(1, 2, 1L, SECONDS, null, new SimpleThreadFactory());
909 shouldThrow();
910 } catch (NullPointerException success) {}
911 }
912
913 /**
914 * Constructor throws if threadFactory is set to null
915 */
916 public void testConstructorNullPointerException3() {
917 try {
918 new CustomTPE(1, 2, 1L, SECONDS,
919 new ArrayBlockingQueue<Runnable>(10),
920 (ThreadFactory) null);
921 shouldThrow();
922 } catch (NullPointerException success) {}
923 }
924
925 /**
926 * Constructor throws if corePoolSize argument is less than zero
927 */
928 public void testConstructor11() {
929 try {
930 new CustomTPE(-1, 1, 1L, SECONDS,
931 new ArrayBlockingQueue<Runnable>(10),
932 new NoOpREHandler());
933 shouldThrow();
934 } catch (IllegalArgumentException success) {}
935 }
936
937 /**
938 * Constructor throws if maximumPoolSize is less than zero
939 */
940 public void testConstructor12() {
941 try {
942 new CustomTPE(1, -1, 1L, SECONDS,
943 new ArrayBlockingQueue<Runnable>(10),
944 new NoOpREHandler());
945 shouldThrow();
946 } catch (IllegalArgumentException success) {}
947 }
948
949 /**
950 * Constructor throws if maximumPoolSize is equal to zero
951 */
952 public void testConstructor13() {
953 try {
954 new CustomTPE(1, 0, 1L, SECONDS,
955 new ArrayBlockingQueue<Runnable>(10),
956 new NoOpREHandler());
957 shouldThrow();
958 } catch (IllegalArgumentException success) {}
959 }
960
961 /**
962 * Constructor throws if keepAliveTime is less than zero
963 */
964 public void testConstructor14() {
965 try {
966 new CustomTPE(1, 2, -1L, SECONDS,
967 new ArrayBlockingQueue<Runnable>(10),
968 new NoOpREHandler());
969 shouldThrow();
970 } catch (IllegalArgumentException success) {}
971 }
972
973 /**
974 * Constructor throws if corePoolSize is greater than the maximumPoolSize
975 */
976 public void testConstructor15() {
977 try {
978 new CustomTPE(2, 1, 1L, SECONDS,
979 new ArrayBlockingQueue<Runnable>(10),
980 new NoOpREHandler());
981 shouldThrow();
982 } catch (IllegalArgumentException success) {}
983 }
984
985 /**
986 * Constructor throws if workQueue is set to null
987 */
988 public void testConstructorNullPointerException4() {
989 try {
990 new CustomTPE(1, 2, 1L, SECONDS,
991 null,
992 new NoOpREHandler());
993 shouldThrow();
994 } catch (NullPointerException success) {}
995 }
996
997 /**
998 * Constructor throws if handler is set to null
999 */
1000 public void testConstructorNullPointerException5() {
1001 try {
1002 new CustomTPE(1, 2, 1L, SECONDS,
1003 new ArrayBlockingQueue<Runnable>(10),
1004 (RejectedExecutionHandler) null);
1005 shouldThrow();
1006 } catch (NullPointerException success) {}
1007 }
1008
1009 /**
1010 * Constructor throws if corePoolSize argument is less than zero
1011 */
1012 public void testConstructor16() {
1013 try {
1014 new CustomTPE(-1, 1, 1L, SECONDS,
1015 new ArrayBlockingQueue<Runnable>(10),
1016 new SimpleThreadFactory(),
1017 new NoOpREHandler());
1018 shouldThrow();
1019 } catch (IllegalArgumentException success) {}
1020 }
1021
1022 /**
1023 * Constructor throws if maximumPoolSize is less than zero
1024 */
1025 public void testConstructor17() {
1026 try {
1027 new CustomTPE(1, -1, 1L, SECONDS,
1028 new ArrayBlockingQueue<Runnable>(10),
1029 new SimpleThreadFactory(),
1030 new NoOpREHandler());
1031 shouldThrow();
1032 } catch (IllegalArgumentException success) {}
1033 }
1034
1035 /**
1036 * Constructor throws if maximumPoolSize is equal to zero
1037 */
1038 public void testConstructor18() {
1039 try {
1040 new CustomTPE(1, 0, 1L, SECONDS,
1041 new ArrayBlockingQueue<Runnable>(10),
1042 new SimpleThreadFactory(),
1043 new NoOpREHandler());
1044 shouldThrow();
1045 } catch (IllegalArgumentException success) {}
1046 }
1047
1048 /**
1049 * Constructor throws if keepAliveTime is less than zero
1050 */
1051 public void testConstructor19() {
1052 try {
1053 new CustomTPE(1, 2, -1L, SECONDS,
1054 new ArrayBlockingQueue<Runnable>(10),
1055 new SimpleThreadFactory(),
1056 new NoOpREHandler());
1057 shouldThrow();
1058 } catch (IllegalArgumentException success) {}
1059 }
1060
1061 /**
1062 * Constructor throws if corePoolSize is greater than the maximumPoolSize
1063 */
1064 public void testConstructor20() {
1065 try {
1066 new CustomTPE(2, 1, 1L, SECONDS,
1067 new ArrayBlockingQueue<Runnable>(10),
1068 new SimpleThreadFactory(),
1069 new NoOpREHandler());
1070 shouldThrow();
1071 } catch (IllegalArgumentException success) {}
1072 }
1073
1074 /**
1075 * Constructor throws if workQueue is null
1076 */
1077 public void testConstructorNullPointerException6() {
1078 try {
1079 new CustomTPE(1, 2, 1L, SECONDS,
1080 null,
1081 new SimpleThreadFactory(),
1082 new NoOpREHandler());
1083 shouldThrow();
1084 } catch (NullPointerException success) {}
1085 }
1086
1087 /**
1088 * Constructor throws if handler is null
1089 */
1090 public void testConstructorNullPointerException7() {
1091 try {
1092 new CustomTPE(1, 2, 1L, SECONDS,
1093 new ArrayBlockingQueue<Runnable>(10),
1094 new SimpleThreadFactory(),
1095 (RejectedExecutionHandler) null);
1096 shouldThrow();
1097 } catch (NullPointerException success) {}
1098 }
1099
1100 /**
1101 * Constructor throws if ThreadFactory is null
1102 */
1103 public void testConstructorNullPointerException8() {
1104 try {
1105 new CustomTPE(1, 2, 1L, SECONDS,
1106 new ArrayBlockingQueue<Runnable>(10),
1107 (ThreadFactory) null,
1108 new NoOpREHandler());
1109 shouldThrow();
1110 } catch (NullPointerException success) {}
1111 }
1112
1113 /**
1114 * execute throws RejectedExecutionException if saturated.
1115 */
1116 public void testSaturatedExecute() {
1117 ThreadPoolExecutor p =
1118 new CustomTPE(1, 1,
1119 LONG_DELAY_MS, MILLISECONDS,
1120 new ArrayBlockingQueue<Runnable>(1));
1121 final CountDownLatch done = new CountDownLatch(1);
1122 try {
1123 Runnable task = new CheckedRunnable() {
1124 public void realRun() throws InterruptedException {
1125 done.await();
1126 }};
1127 for (int i = 0; i < 2; ++i)
1128 p.execute(task);
1129 for (int i = 0; i < 2; ++i) {
1130 try {
1131 p.execute(task);
1132 shouldThrow();
1133 } catch (RejectedExecutionException success) {}
1134 assertTrue(p.getTaskCount() <= 2);
1135 }
1136 } finally {
1137 done.countDown();
1138 joinPool(p);
1139 }
1140 }
1141
1142 /**
1143 * executor using CallerRunsPolicy runs task if saturated.
1144 */
1145 public void testSaturatedExecute2() {
1146 RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
1147 ThreadPoolExecutor p = new CustomTPE(1, 1,
1148 LONG_DELAY_MS, MILLISECONDS,
1149 new ArrayBlockingQueue<Runnable>(1),
1150 h);
1151 try {
1152 TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
1153 for (int i = 0; i < tasks.length; ++i)
1154 tasks[i] = new TrackedNoOpRunnable();
1155 TrackedLongRunnable mr = new TrackedLongRunnable();
1156 p.execute(mr);
1157 for (int i = 0; i < tasks.length; ++i)
1158 p.execute(tasks[i]);
1159 for (int i = 1; i < tasks.length; ++i)
1160 assertTrue(tasks[i].done);
1161 try { p.shutdownNow(); } catch (SecurityException ok) { return; }
1162 } finally {
1163 joinPool(p);
1164 }
1165 }
1166
1167 /**
1168 * executor using DiscardPolicy drops task if saturated.
1169 */
1170 public void testSaturatedExecute3() {
1171 RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
1172 ThreadPoolExecutor p =
1173 new CustomTPE(1, 1,
1174 LONG_DELAY_MS, MILLISECONDS,
1175 new ArrayBlockingQueue<Runnable>(1),
1176 h);
1177 try {
1178 TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
1179 for (int i = 0; i < tasks.length; ++i)
1180 tasks[i] = new TrackedNoOpRunnable();
1181 p.execute(new TrackedLongRunnable());
1182 for (TrackedNoOpRunnable task : tasks)
1183 p.execute(task);
1184 for (TrackedNoOpRunnable task : tasks)
1185 assertFalse(task.done);
1186 try { p.shutdownNow(); } catch (SecurityException ok) { return; }
1187 } finally {
1188 joinPool(p);
1189 }
1190 }
1191
1192 /**
1193 * executor using DiscardOldestPolicy drops oldest task if saturated.
1194 */
1195 public void testSaturatedExecute4() {
1196 RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
1197 ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1198 try {
1199 p.execute(new TrackedLongRunnable());
1200 TrackedLongRunnable r2 = new TrackedLongRunnable();
1201 p.execute(r2);
1202 assertTrue(p.getQueue().contains(r2));
1203 TrackedNoOpRunnable r3 = new TrackedNoOpRunnable();
1204 p.execute(r3);
1205 assertFalse(p.getQueue().contains(r2));
1206 assertTrue(p.getQueue().contains(r3));
1207 try { p.shutdownNow(); } catch (SecurityException ok) { return; }
1208 } finally {
1209 joinPool(p);
1210 }
1211 }
1212
1213 /**
1214 * execute throws RejectedExecutionException if shutdown
1215 */
1216 public void testRejectedExecutionExceptionOnShutdown() {
1217 ThreadPoolExecutor p =
1218 new CustomTPE(1,1,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(1));
1219 try { p.shutdown(); } catch (SecurityException ok) { return; }
1220 try {
1221 p.execute(new NoOpRunnable());
1222 shouldThrow();
1223 } catch (RejectedExecutionException success) {}
1224
1225 joinPool(p);
1226 }
1227
1228 /**
1229 * execute using CallerRunsPolicy drops task on shutdown
1230 */
1231 public void testCallerRunsOnShutdown() {
1232 RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
1233 ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1234
1235 try { p.shutdown(); } catch (SecurityException ok) { return; }
1236 try {
1237 TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1238 p.execute(r);
1239 assertFalse(r.done);
1240 } finally {
1241 joinPool(p);
1242 }
1243 }
1244
1245 /**
1246 * execute using DiscardPolicy drops task on shutdown
1247 */
1248 public void testDiscardOnShutdown() {
1249 RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
1250 ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1251
1252 try { p.shutdown(); } catch (SecurityException ok) { return; }
1253 try {
1254 TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1255 p.execute(r);
1256 assertFalse(r.done);
1257 } finally {
1258 joinPool(p);
1259 }
1260 }
1261
1262 /**
1263 * execute using DiscardOldestPolicy drops task on shutdown
1264 */
1265 public void testDiscardOldestOnShutdown() {
1266 RejectedExecutionHandler h = new CustomTPE.DiscardOldestPolicy();
1267 ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1268
1269 try { p.shutdown(); } catch (SecurityException ok) { return; }
1270 try {
1271 TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1272 p.execute(r);
1273 assertFalse(r.done);
1274 } finally {
1275 joinPool(p);
1276 }
1277 }
1278
1279 /**
1280 * execute(null) throws NPE
1281 */
1282 public void testExecuteNull() {
1283 ThreadPoolExecutor p =
1284 new CustomTPE(1, 2, 1L, SECONDS,
1285 new ArrayBlockingQueue<Runnable>(10));
1286 try {
1287 p.execute(null);
1288 shouldThrow();
1289 } catch (NullPointerException success) {}
1290
1291 joinPool(p);
1292 }
1293
1294 /**
1295 * setCorePoolSize of negative value throws IllegalArgumentException
1296 */
1297 public void testCorePoolSizeIllegalArgumentException() {
1298 ThreadPoolExecutor p =
1299 new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1300 try {
1301 p.setCorePoolSize(-1);
1302 shouldThrow();
1303 } catch (IllegalArgumentException success) {
1304 } finally {
1305 try { p.shutdown(); } catch (SecurityException ok) { return; }
1306 }
1307 joinPool(p);
1308 }
1309
1310 /**
1311 * setMaximumPoolSize(int) throws IllegalArgumentException
1312 * if given a value less the core pool size
1313 */
1314 public void testMaximumPoolSizeIllegalArgumentException() {
1315 ThreadPoolExecutor p =
1316 new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1317 try {
1318 p.setMaximumPoolSize(1);
1319 shouldThrow();
1320 } catch (IllegalArgumentException success) {
1321 } finally {
1322 try { p.shutdown(); } catch (SecurityException ok) { return; }
1323 }
1324 joinPool(p);
1325 }
1326
1327 /**
1328 * setMaximumPoolSize throws IllegalArgumentException
1329 * if given a negative value
1330 */
1331 public void testMaximumPoolSizeIllegalArgumentException2() {
1332 ThreadPoolExecutor p =
1333 new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1334 try {
1335 p.setMaximumPoolSize(-1);
1336 shouldThrow();
1337 } catch (IllegalArgumentException success) {
1338 } finally {
1339 try { p.shutdown(); } catch (SecurityException ok) { return; }
1340 }
1341 joinPool(p);
1342 }
1343
1344 /**
1345 * setKeepAliveTime throws IllegalArgumentException
1346 * when given a negative value
1347 */
1348 public void testKeepAliveTimeIllegalArgumentException() {
1349 ThreadPoolExecutor p =
1350 new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1351
1352 try {
1353 p.setKeepAliveTime(-1,MILLISECONDS);
1354 shouldThrow();
1355 } catch (IllegalArgumentException success) {
1356 } finally {
1357 try { p.shutdown(); } catch (SecurityException ok) { return; }
1358 }
1359 joinPool(p);
1360 }
1361
1362 /**
1363 * terminated() is called on termination
1364 */
1365 public void testTerminated() {
1366 CustomTPE p = new CustomTPE();
1367 try { p.shutdown(); } catch (SecurityException ok) { return; }
1368 assertTrue(p.terminatedCalled());
1369 joinPool(p);
1370 }
1371
1372 /**
1373 * beforeExecute and afterExecute are called when executing task
1374 */
1375 public void testBeforeAfter() throws InterruptedException {
1376 CustomTPE p = new CustomTPE();
1377 try {
1378 final CountDownLatch done = new CountDownLatch(1);
1379 p.execute(new CheckedRunnable() {
1380 public void realRun() {
1381 done.countDown();
1382 }});
1383 await(p.afterCalled);
1384 assertEquals(0, done.getCount());
1385 assertTrue(p.afterCalled());
1386 assertTrue(p.beforeCalled());
1387 try { p.shutdown(); } catch (SecurityException ok) { return; }
1388 } finally {
1389 joinPool(p);
1390 }
1391 }
1392
1393 /**
1394 * completed submit of callable returns result
1395 */
1396 public void testSubmitCallable() throws Exception {
1397 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1398 try {
1399 Future<String> future = e.submit(new StringTask());
1400 String result = future.get();
1401 assertSame(TEST_STRING, result);
1402 } finally {
1403 joinPool(e);
1404 }
1405 }
1406
1407 /**
1408 * completed submit of runnable returns successfully
1409 */
1410 public void testSubmitRunnable() throws Exception {
1411 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1412 try {
1413 Future<?> future = e.submit(new NoOpRunnable());
1414 future.get();
1415 assertTrue(future.isDone());
1416 } finally {
1417 joinPool(e);
1418 }
1419 }
1420
1421 /**
1422 * completed submit of (runnable, result) returns result
1423 */
1424 public void testSubmitRunnable2() throws Exception {
1425 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1426 try {
1427 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
1428 String result = future.get();
1429 assertSame(TEST_STRING, result);
1430 } finally {
1431 joinPool(e);
1432 }
1433 }
1434
1435 /**
1436 * invokeAny(null) throws NPE
1437 */
1438 public void testInvokeAny1() throws Exception {
1439 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1440 try {
1441 e.invokeAny(null);
1442 shouldThrow();
1443 } catch (NullPointerException success) {
1444 } finally {
1445 joinPool(e);
1446 }
1447 }
1448
1449 /**
1450 * invokeAny(empty collection) throws IAE
1451 */
1452 public void testInvokeAny2() throws Exception {
1453 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1454 try {
1455 e.invokeAny(new ArrayList<Callable<String>>());
1456 shouldThrow();
1457 } catch (IllegalArgumentException success) {
1458 } finally {
1459 joinPool(e);
1460 }
1461 }
1462
1463 /**
1464 * invokeAny(c) throws NPE if c has null elements
1465 */
1466 public void testInvokeAny3() throws Exception {
1467 CountDownLatch latch = new CountDownLatch(1);
1468 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1469 List<Callable<String>> l = new ArrayList<Callable<String>>();
1470 l.add(latchAwaitingStringTask(latch));
1471 l.add(null);
1472 try {
1473 e.invokeAny(l);
1474 shouldThrow();
1475 } catch (NullPointerException success) {
1476 } finally {
1477 latch.countDown();
1478 joinPool(e);
1479 }
1480 }
1481
1482 /**
1483 * invokeAny(c) throws ExecutionException if no task completes
1484 */
1485 public void testInvokeAny4() throws Exception {
1486 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1487 List<Callable<String>> l = new ArrayList<Callable<String>>();
1488 l.add(new NPETask());
1489 try {
1490 e.invokeAny(l);
1491 shouldThrow();
1492 } catch (ExecutionException success) {
1493 assertTrue(success.getCause() instanceof NullPointerException);
1494 } finally {
1495 joinPool(e);
1496 }
1497 }
1498
1499 /**
1500 * invokeAny(c) returns result of some task
1501 */
1502 public void testInvokeAny5() throws Exception {
1503 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1504 try {
1505 List<Callable<String>> l = new ArrayList<Callable<String>>();
1506 l.add(new StringTask());
1507 l.add(new StringTask());
1508 String result = e.invokeAny(l);
1509 assertSame(TEST_STRING, result);
1510 } finally {
1511 joinPool(e);
1512 }
1513 }
1514
1515 /**
1516 * invokeAll(null) throws NPE
1517 */
1518 public void testInvokeAll1() throws Exception {
1519 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1520 try {
1521 e.invokeAll(null);
1522 shouldThrow();
1523 } catch (NullPointerException success) {
1524 } finally {
1525 joinPool(e);
1526 }
1527 }
1528
1529 /**
1530 * invokeAll(empty collection) returns empty collection
1531 */
1532 public void testInvokeAll2() throws Exception {
1533 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1534 try {
1535 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
1536 assertTrue(r.isEmpty());
1537 } finally {
1538 joinPool(e);
1539 }
1540 }
1541
1542 /**
1543 * invokeAll(c) throws NPE if c has null elements
1544 */
1545 public void testInvokeAll3() throws Exception {
1546 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1547 List<Callable<String>> l = new ArrayList<Callable<String>>();
1548 l.add(new StringTask());
1549 l.add(null);
1550 try {
1551 e.invokeAll(l);
1552 shouldThrow();
1553 } catch (NullPointerException success) {
1554 } finally {
1555 joinPool(e);
1556 }
1557 }
1558
1559 /**
1560 * get of element of invokeAll(c) throws exception on failed task
1561 */
1562 public void testInvokeAll4() throws Exception {
1563 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1564 List<Callable<String>> l = new ArrayList<Callable<String>>();
1565 l.add(new NPETask());
1566 List<Future<String>> futures = e.invokeAll(l);
1567 assertEquals(1, futures.size());
1568 try {
1569 futures.get(0).get();
1570 shouldThrow();
1571 } catch (ExecutionException success) {
1572 assertTrue(success.getCause() instanceof NullPointerException);
1573 } finally {
1574 joinPool(e);
1575 }
1576 }
1577
1578 /**
1579 * invokeAll(c) returns results of all completed tasks
1580 */
1581 public void testInvokeAll5() throws Exception {
1582 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1583 try {
1584 List<Callable<String>> l = new ArrayList<Callable<String>>();
1585 l.add(new StringTask());
1586 l.add(new StringTask());
1587 List<Future<String>> futures = e.invokeAll(l);
1588 assertEquals(2, futures.size());
1589 for (Future<String> future : futures)
1590 assertSame(TEST_STRING, future.get());
1591 } finally {
1592 joinPool(e);
1593 }
1594 }
1595
1596 /**
1597 * timed invokeAny(null) throws NPE
1598 */
1599 public void testTimedInvokeAny1() throws Exception {
1600 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1601 try {
1602 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
1603 shouldThrow();
1604 } catch (NullPointerException success) {
1605 } finally {
1606 joinPool(e);
1607 }
1608 }
1609
1610 /**
1611 * timed invokeAny(,,null) throws NPE
1612 */
1613 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
1614 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1615 List<Callable<String>> l = new ArrayList<Callable<String>>();
1616 l.add(new StringTask());
1617 try {
1618 e.invokeAny(l, MEDIUM_DELAY_MS, null);
1619 shouldThrow();
1620 } catch (NullPointerException success) {
1621 } finally {
1622 joinPool(e);
1623 }
1624 }
1625
1626 /**
1627 * timed invokeAny(empty collection) throws IAE
1628 */
1629 public void testTimedInvokeAny2() throws Exception {
1630 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1631 try {
1632 e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1633 shouldThrow();
1634 } catch (IllegalArgumentException success) {
1635 } finally {
1636 joinPool(e);
1637 }
1638 }
1639
1640 /**
1641 * timed invokeAny(c) throws NPE if c has null elements
1642 */
1643 public void testTimedInvokeAny3() throws Exception {
1644 CountDownLatch latch = new CountDownLatch(1);
1645 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1646 List<Callable<String>> l = new ArrayList<Callable<String>>();
1647 l.add(latchAwaitingStringTask(latch));
1648 l.add(null);
1649 try {
1650 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1651 shouldThrow();
1652 } catch (NullPointerException success) {
1653 } finally {
1654 latch.countDown();
1655 joinPool(e);
1656 }
1657 }
1658
1659 /**
1660 * timed invokeAny(c) throws ExecutionException if no task completes
1661 */
1662 public void testTimedInvokeAny4() throws Exception {
1663 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1664 List<Callable<String>> l = new ArrayList<Callable<String>>();
1665 l.add(new NPETask());
1666 try {
1667 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1668 shouldThrow();
1669 } catch (ExecutionException success) {
1670 assertTrue(success.getCause() instanceof NullPointerException);
1671 } finally {
1672 joinPool(e);
1673 }
1674 }
1675
1676 /**
1677 * timed invokeAny(c) returns result of some task
1678 */
1679 public void testTimedInvokeAny5() throws Exception {
1680 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1681 try {
1682 List<Callable<String>> l = new ArrayList<Callable<String>>();
1683 l.add(new StringTask());
1684 l.add(new StringTask());
1685 String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1686 assertSame(TEST_STRING, result);
1687 } finally {
1688 joinPool(e);
1689 }
1690 }
1691
1692 /**
1693 * timed invokeAll(null) throws NPE
1694 */
1695 public void testTimedInvokeAll1() throws Exception {
1696 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1697 try {
1698 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
1699 shouldThrow();
1700 } catch (NullPointerException success) {
1701 } finally {
1702 joinPool(e);
1703 }
1704 }
1705
1706 /**
1707 * timed invokeAll(,,null) throws NPE
1708 */
1709 public void testTimedInvokeAllNullTimeUnit() throws Exception {
1710 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1711 List<Callable<String>> l = new ArrayList<Callable<String>>();
1712 l.add(new StringTask());
1713 try {
1714 e.invokeAll(l, MEDIUM_DELAY_MS, null);
1715 shouldThrow();
1716 } catch (NullPointerException success) {
1717 } finally {
1718 joinPool(e);
1719 }
1720 }
1721
1722 /**
1723 * timed invokeAll(empty collection) returns empty collection
1724 */
1725 public void testTimedInvokeAll2() throws Exception {
1726 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1727 try {
1728 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1729 assertTrue(r.isEmpty());
1730 } finally {
1731 joinPool(e);
1732 }
1733 }
1734
1735 /**
1736 * timed invokeAll(c) throws NPE if c has null elements
1737 */
1738 public void testTimedInvokeAll3() throws Exception {
1739 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1740 List<Callable<String>> l = new ArrayList<Callable<String>>();
1741 l.add(new StringTask());
1742 l.add(null);
1743 try {
1744 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1745 shouldThrow();
1746 } catch (NullPointerException success) {
1747 } finally {
1748 joinPool(e);
1749 }
1750 }
1751
1752 /**
1753 * get of element of invokeAll(c) throws exception on failed task
1754 */
1755 public void testTimedInvokeAll4() throws Exception {
1756 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1757 List<Callable<String>> l = new ArrayList<Callable<String>>();
1758 l.add(new NPETask());
1759 List<Future<String>> futures =
1760 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1761 assertEquals(1, futures.size());
1762 try {
1763 futures.get(0).get();
1764 shouldThrow();
1765 } catch (ExecutionException success) {
1766 assertTrue(success.getCause() instanceof NullPointerException);
1767 } finally {
1768 joinPool(e);
1769 }
1770 }
1771
1772 /**
1773 * timed invokeAll(c) returns results of all completed tasks
1774 */
1775 public void testTimedInvokeAll5() throws Exception {
1776 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1777 try {
1778 List<Callable<String>> l = new ArrayList<Callable<String>>();
1779 l.add(new StringTask());
1780 l.add(new StringTask());
1781 List<Future<String>> futures =
1782 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1783 assertEquals(2, futures.size());
1784 for (Future<String> future : futures)
1785 assertSame(TEST_STRING, future.get());
1786 } finally {
1787 joinPool(e);
1788 }
1789 }
1790
1791 /**
1792 * timed invokeAll(c) cancels tasks not completed by timeout
1793 */
1794 public void testTimedInvokeAll6() throws Exception {
1795 ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1796 try {
1797 for (long timeout = timeoutMillis();;) {
1798 List<Callable<String>> tasks = new ArrayList<>();
1799 tasks.add(new StringTask("0"));
1800 tasks.add(Executors.callable(new LongPossiblyInterruptedRunnable(), TEST_STRING));
1801 tasks.add(new StringTask("2"));
1802 long startTime = System.nanoTime();
1803 List<Future<String>> futures =
1804 e.invokeAll(tasks, timeout, MILLISECONDS);
1805 assertEquals(tasks.size(), futures.size());
1806 assertTrue(millisElapsedSince(startTime) >= timeout);
1807 for (Future future : futures)
1808 assertTrue(future.isDone());
1809 assertTrue(futures.get(1).isCancelled());
1810 try {
1811 assertEquals("0", futures.get(0).get());
1812 assertEquals("2", futures.get(2).get());
1813 break;
1814 } catch (CancellationException retryWithLongerTimeout) {
1815 timeout *= 2;
1816 if (timeout >= LONG_DELAY_MS / 2)
1817 fail("expected exactly one task to be cancelled");
1818 }
1819 }
1820 } finally {
1821 joinPool(e);
1822 }
1823 }
1824
1825 /**
1826 * Execution continues if there is at least one thread even if
1827 * thread factory fails to create more
1828 */
1829 public void testFailingThreadFactory() throws InterruptedException {
1830 final ExecutorService e =
1831 new CustomTPE(100, 100,
1832 LONG_DELAY_MS, MILLISECONDS,
1833 new LinkedBlockingQueue<Runnable>(),
1834 new FailingThreadFactory());
1835 try {
1836 final int TASKS = 100;
1837 final CountDownLatch done = new CountDownLatch(TASKS);
1838 for (int k = 0; k < TASKS; ++k)
1839 e.execute(new CheckedRunnable() {
1840 public void realRun() {
1841 done.countDown();
1842 }});
1843 assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
1844 } finally {
1845 joinPool(e);
1846 }
1847 }
1848
1849 /**
1850 * allowsCoreThreadTimeOut is by default false.
1851 */
1852 public void testAllowsCoreThreadTimeOut() {
1853 ThreadPoolExecutor p = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1854 assertFalse(p.allowsCoreThreadTimeOut());
1855 joinPool(p);
1856 }
1857
1858 /**
1859 * allowCoreThreadTimeOut(true) causes idle threads to time out
1860 */
1861 public void testAllowCoreThreadTimeOut_true() throws Exception {
1862 long keepAliveTime = timeoutMillis();
1863 final ThreadPoolExecutor p =
1864 new CustomTPE(2, 10,
1865 keepAliveTime, MILLISECONDS,
1866 new ArrayBlockingQueue<Runnable>(10));
1867 final CountDownLatch threadStarted = new CountDownLatch(1);
1868 try {
1869 p.allowCoreThreadTimeOut(true);
1870 p.execute(new CheckedRunnable() {
1871 public void realRun() {
1872 threadStarted.countDown();
1873 assertEquals(1, p.getPoolSize());
1874 }});
1875 await(threadStarted);
1876 delay(keepAliveTime);
1877 long startTime = System.nanoTime();
1878 while (p.getPoolSize() > 0
1879 && millisElapsedSince(startTime) < LONG_DELAY_MS)
1880 Thread.yield();
1881 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1882 assertEquals(0, p.getPoolSize());
1883 } finally {
1884 joinPool(p);
1885 }
1886 }
1887
1888 /**
1889 * allowCoreThreadTimeOut(false) causes idle threads not to time out
1890 */
1891 public void testAllowCoreThreadTimeOut_false() throws Exception {
1892 long keepAliveTime = timeoutMillis();
1893 final ThreadPoolExecutor p =
1894 new CustomTPE(2, 10,
1895 keepAliveTime, MILLISECONDS,
1896 new ArrayBlockingQueue<Runnable>(10));
1897 final CountDownLatch threadStarted = new CountDownLatch(1);
1898 try {
1899 p.allowCoreThreadTimeOut(false);
1900 p.execute(new CheckedRunnable() {
1901 public void realRun() throws InterruptedException {
1902 threadStarted.countDown();
1903 assertTrue(p.getPoolSize() >= 1);
1904 }});
1905 delay(2 * keepAliveTime);
1906 assertTrue(p.getPoolSize() >= 1);
1907 } finally {
1908 joinPool(p);
1909 }
1910 }
1911
1912 /**
1913 * get(cancelled task) throws CancellationException
1914 * (in part, a test of CustomTPE itself)
1915 */
1916 public void testGet_cancelled() throws Exception {
1917 final ExecutorService e =
1918 new CustomTPE(1, 1,
1919 LONG_DELAY_MS, MILLISECONDS,
1920 new LinkedBlockingQueue<Runnable>());
1921 try {
1922 final CountDownLatch blockerStarted = new CountDownLatch(1);
1923 final CountDownLatch done = new CountDownLatch(1);
1924 final List<Future<?>> futures = new ArrayList<>();
1925 for (int i = 0; i < 2; i++) {
1926 Runnable r = new CheckedRunnable() { public void realRun()
1927 throws Throwable {
1928 blockerStarted.countDown();
1929 assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
1930 }};
1931 futures.add(e.submit(r));
1932 }
1933 assertTrue(blockerStarted.await(LONG_DELAY_MS, MILLISECONDS));
1934 for (Future<?> future : futures) future.cancel(false);
1935 for (Future<?> future : futures) {
1936 try {
1937 future.get();
1938 shouldThrow();
1939 } catch (CancellationException success) {}
1940 try {
1941 future.get(LONG_DELAY_MS, MILLISECONDS);
1942 shouldThrow();
1943 } catch (CancellationException success) {}
1944 assertTrue(future.isCancelled());
1945 assertTrue(future.isDone());
1946 }
1947 done.countDown();
1948 } finally {
1949 joinPool(e);
1950 }
1951 }
1952
1953 }