ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.61
Committed: Sun Oct 4 02:00:19 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.60: +9 -7 lines
Log Message:
improve testSetRejectedExecutionHandlerNull

File Contents

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