ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.69
Committed: Sun Oct 4 02:29:46 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.68: +6 -7 lines
Log Message:
improve testIsTerminated

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