ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java
Revision: 1.67
Committed: Sun Oct 4 02:24:49 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.66: +3 -5 lines
Log Message:
improve testGetTaskCount

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