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

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