ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.41
Committed: Mon Sep 28 03:05:23 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.40: +3 -0 lines
Log Message:
improve tests for shutdownNow

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 */
6
7 import static java.util.concurrent.TimeUnit.MILLISECONDS;
8 import static java.util.concurrent.TimeUnit.SECONDS;
9
10 import java.util.ArrayList;
11 import java.util.HashSet;
12 import java.util.List;
13 import java.util.concurrent.BlockingQueue;
14 import java.util.concurrent.Callable;
15 import java.util.concurrent.CancellationException;
16 import java.util.concurrent.CountDownLatch;
17 import java.util.concurrent.Delayed;
18 import java.util.concurrent.ExecutionException;
19 import java.util.concurrent.Executors;
20 import java.util.concurrent.ExecutorService;
21 import java.util.concurrent.Future;
22 import java.util.concurrent.RejectedExecutionException;
23 import java.util.concurrent.RejectedExecutionHandler;
24 import java.util.concurrent.RunnableScheduledFuture;
25 import java.util.concurrent.ScheduledFuture;
26 import java.util.concurrent.ScheduledThreadPoolExecutor;
27 import java.util.concurrent.ThreadFactory;
28 import java.util.concurrent.ThreadPoolExecutor;
29 import java.util.concurrent.TimeoutException;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.atomic.AtomicInteger;
32
33 import junit.framework.Test;
34 import junit.framework.TestSuite;
35
36 public class ScheduledExecutorSubclassTest extends JSR166TestCase {
37 public static void main(String[] args) {
38 main(suite(), args);
39 }
40 public static Test suite() {
41 return new TestSuite(ScheduledExecutorSubclassTest.class);
42 }
43
44 static class CustomTask<V> implements RunnableScheduledFuture<V> {
45 RunnableScheduledFuture<V> task;
46 volatile boolean ran;
47 CustomTask(RunnableScheduledFuture<V> t) { task = t; }
48 public boolean isPeriodic() { return task.isPeriodic(); }
49 public void run() {
50 ran = true;
51 task.run();
52 }
53 public long getDelay(TimeUnit unit) { return task.getDelay(unit); }
54 public int compareTo(Delayed t) {
55 return task.compareTo(((CustomTask)t).task);
56 }
57 public boolean cancel(boolean mayInterruptIfRunning) {
58 return task.cancel(mayInterruptIfRunning);
59 }
60 public boolean isCancelled() { return task.isCancelled(); }
61 public boolean isDone() { return task.isDone(); }
62 public V get() throws InterruptedException, ExecutionException {
63 V v = task.get();
64 assertTrue(ran);
65 return v;
66 }
67 public V get(long time, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
68 V v = task.get(time, unit);
69 assertTrue(ran);
70 return v;
71 }
72 }
73
74 public class CustomExecutor extends ScheduledThreadPoolExecutor {
75
76 protected <V> RunnableScheduledFuture<V> decorateTask(Runnable r, RunnableScheduledFuture<V> task) {
77 return new CustomTask<V>(task);
78 }
79
80 protected <V> RunnableScheduledFuture<V> decorateTask(Callable<V> c, RunnableScheduledFuture<V> task) {
81 return new CustomTask<V>(task);
82 }
83 CustomExecutor(int corePoolSize) { super(corePoolSize); }
84 CustomExecutor(int corePoolSize, RejectedExecutionHandler handler) {
85 super(corePoolSize, handler);
86 }
87
88 CustomExecutor(int corePoolSize, ThreadFactory threadFactory) {
89 super(corePoolSize, threadFactory);
90 }
91 CustomExecutor(int corePoolSize, ThreadFactory threadFactory,
92 RejectedExecutionHandler handler) {
93 super(corePoolSize, threadFactory, handler);
94 }
95
96 }
97
98 /**
99 * execute successfully executes a runnable
100 */
101 public void testExecute() throws InterruptedException {
102 CustomExecutor p = new CustomExecutor(1);
103 final CountDownLatch done = new CountDownLatch(1);
104 final Runnable task = new CheckedRunnable() {
105 public void realRun() {
106 done.countDown();
107 }};
108 try {
109 p.execute(task);
110 assertTrue(done.await(SMALL_DELAY_MS, MILLISECONDS));
111 } finally {
112 joinPool(p);
113 }
114 }
115
116 /**
117 * delayed schedule of callable successfully executes after delay
118 */
119 public void testSchedule1() throws Exception {
120 CustomExecutor p = new CustomExecutor(1);
121 final long startTime = System.nanoTime();
122 final CountDownLatch done = new CountDownLatch(1);
123 try {
124 Callable task = new CheckedCallable<Boolean>() {
125 public Boolean realCall() {
126 done.countDown();
127 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
128 return Boolean.TRUE;
129 }};
130 Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
131 assertSame(Boolean.TRUE, f.get());
132 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
133 assertTrue(done.await(0L, MILLISECONDS));
134 } finally {
135 joinPool(p);
136 }
137 }
138
139 /**
140 * delayed schedule of runnable successfully executes after delay
141 */
142 public void testSchedule3() throws Exception {
143 CustomExecutor p = new CustomExecutor(1);
144 final long startTime = System.nanoTime();
145 final CountDownLatch done = new CountDownLatch(1);
146 try {
147 Runnable task = new CheckedRunnable() {
148 public void realRun() {
149 done.countDown();
150 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
151 }};
152 Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
153 await(done);
154 assertNull(f.get(LONG_DELAY_MS, MILLISECONDS));
155 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
156 } finally {
157 joinPool(p);
158 }
159 }
160
161 /**
162 * scheduleAtFixedRate executes runnable after given initial delay
163 */
164 public void testSchedule4() throws InterruptedException {
165 CustomExecutor p = new CustomExecutor(1);
166 final long startTime = System.nanoTime();
167 final CountDownLatch done = new CountDownLatch(1);
168 try {
169 Runnable task = new CheckedRunnable() {
170 public void realRun() {
171 done.countDown();
172 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
173 }};
174 ScheduledFuture f =
175 p.scheduleAtFixedRate(task, timeoutMillis(),
176 LONG_DELAY_MS, MILLISECONDS);
177 await(done);
178 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
179 f.cancel(true);
180 } finally {
181 joinPool(p);
182 }
183 }
184
185 /**
186 * scheduleWithFixedDelay executes runnable after given initial delay
187 */
188 public void testSchedule5() throws InterruptedException {
189 CustomExecutor p = new CustomExecutor(1);
190 final long startTime = System.nanoTime();
191 final CountDownLatch done = new CountDownLatch(1);
192 try {
193 Runnable task = new CheckedRunnable() {
194 public void realRun() {
195 done.countDown();
196 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
197 }};
198 ScheduledFuture f =
199 p.scheduleWithFixedDelay(task, timeoutMillis(),
200 LONG_DELAY_MS, MILLISECONDS);
201 await(done);
202 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
203 f.cancel(true);
204 } finally {
205 joinPool(p);
206 }
207 }
208
209 static class RunnableCounter implements Runnable {
210 AtomicInteger count = new AtomicInteger(0);
211 public void run() { count.getAndIncrement(); }
212 }
213
214 /**
215 * scheduleAtFixedRate executes series of tasks at given rate
216 */
217 public void testFixedRateSequence() throws InterruptedException {
218 CustomExecutor p = new CustomExecutor(1);
219 try {
220 for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
221 long startTime = System.nanoTime();
222 int cycles = 10;
223 final CountDownLatch done = new CountDownLatch(cycles);
224 Runnable task = new CheckedRunnable() {
225 public void realRun() { done.countDown(); }};
226 ScheduledFuture h =
227 p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
228 done.await();
229 h.cancel(true);
230 double normalizedTime =
231 (double) millisElapsedSince(startTime) / delay;
232 if (normalizedTime >= cycles - 1 &&
233 normalizedTime <= cycles)
234 return;
235 }
236 throw new AssertionError("unexpected execution rate");
237 } finally {
238 joinPool(p);
239 }
240 }
241
242 /**
243 * scheduleWithFixedDelay executes series of tasks with given period
244 */
245 public void testFixedDelaySequence() throws InterruptedException {
246 CustomExecutor p = new CustomExecutor(1);
247 try {
248 for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
249 long startTime = System.nanoTime();
250 int cycles = 10;
251 final CountDownLatch done = new CountDownLatch(cycles);
252 Runnable task = new CheckedRunnable() {
253 public void realRun() { done.countDown(); }};
254 ScheduledFuture h =
255 p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
256 done.await();
257 h.cancel(true);
258 double normalizedTime =
259 (double) millisElapsedSince(startTime) / delay;
260 if (normalizedTime >= cycles - 1 &&
261 normalizedTime <= cycles)
262 return;
263 }
264 throw new AssertionError("unexpected execution rate");
265 } finally {
266 joinPool(p);
267 }
268 }
269
270 /**
271 * execute(null) throws NPE
272 */
273 public void testExecuteNull() throws InterruptedException {
274 CustomExecutor se = new CustomExecutor(1);
275 try {
276 se.execute(null);
277 shouldThrow();
278 } catch (NullPointerException success) {}
279 joinPool(se);
280 }
281
282 /**
283 * schedule(null) throws NPE
284 */
285 public void testScheduleNull() throws InterruptedException {
286 CustomExecutor se = new CustomExecutor(1);
287 try {
288 TrackedCallable callable = null;
289 Future f = se.schedule(callable, SHORT_DELAY_MS, MILLISECONDS);
290 shouldThrow();
291 } catch (NullPointerException success) {}
292 joinPool(se);
293 }
294
295 /**
296 * execute throws RejectedExecutionException if shutdown
297 */
298 public void testSchedule1_RejectedExecutionException() {
299 CustomExecutor se = new CustomExecutor(1);
300 try {
301 se.shutdown();
302 se.schedule(new NoOpRunnable(),
303 MEDIUM_DELAY_MS, MILLISECONDS);
304 shouldThrow();
305 } catch (RejectedExecutionException success) {
306 } catch (SecurityException ok) {
307 }
308
309 joinPool(se);
310 }
311
312 /**
313 * schedule throws RejectedExecutionException if shutdown
314 */
315 public void testSchedule2_RejectedExecutionException() {
316 CustomExecutor se = new CustomExecutor(1);
317 try {
318 se.shutdown();
319 se.schedule(new NoOpCallable(),
320 MEDIUM_DELAY_MS, MILLISECONDS);
321 shouldThrow();
322 } catch (RejectedExecutionException success) {
323 } catch (SecurityException ok) {
324 }
325 joinPool(se);
326 }
327
328 /**
329 * schedule callable throws RejectedExecutionException if shutdown
330 */
331 public void testSchedule3_RejectedExecutionException() {
332 CustomExecutor se = new CustomExecutor(1);
333 try {
334 se.shutdown();
335 se.schedule(new NoOpCallable(),
336 MEDIUM_DELAY_MS, MILLISECONDS);
337 shouldThrow();
338 } catch (RejectedExecutionException success) {
339 } catch (SecurityException ok) {
340 }
341 joinPool(se);
342 }
343
344 /**
345 * scheduleAtFixedRate throws RejectedExecutionException if shutdown
346 */
347 public void testScheduleAtFixedRate1_RejectedExecutionException() {
348 CustomExecutor se = new CustomExecutor(1);
349 try {
350 se.shutdown();
351 se.scheduleAtFixedRate(new NoOpRunnable(),
352 MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
353 shouldThrow();
354 } catch (RejectedExecutionException success) {
355 } catch (SecurityException ok) {
356 }
357 joinPool(se);
358 }
359
360 /**
361 * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
362 */
363 public void testScheduleWithFixedDelay1_RejectedExecutionException() {
364 CustomExecutor se = new CustomExecutor(1);
365 try {
366 se.shutdown();
367 se.scheduleWithFixedDelay(new NoOpRunnable(),
368 MEDIUM_DELAY_MS, MEDIUM_DELAY_MS, MILLISECONDS);
369 shouldThrow();
370 } catch (RejectedExecutionException success) {
371 } catch (SecurityException ok) {
372 }
373 joinPool(se);
374 }
375
376 /**
377 * getActiveCount increases but doesn't overestimate, when a
378 * thread becomes active
379 */
380 public void testGetActiveCount() throws InterruptedException {
381 final ThreadPoolExecutor p = new CustomExecutor(2);
382 final CountDownLatch threadStarted = new CountDownLatch(1);
383 final CountDownLatch done = new CountDownLatch(1);
384 try {
385 assertEquals(0, p.getActiveCount());
386 p.execute(new CheckedRunnable() {
387 public void realRun() throws InterruptedException {
388 threadStarted.countDown();
389 assertEquals(1, p.getActiveCount());
390 done.await();
391 }});
392 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
393 assertEquals(1, p.getActiveCount());
394 } finally {
395 done.countDown();
396 joinPool(p);
397 }
398 }
399
400 /**
401 * getCompletedTaskCount increases, but doesn't overestimate,
402 * when tasks complete
403 */
404 public void testGetCompletedTaskCount() throws InterruptedException {
405 final ThreadPoolExecutor p = new CustomExecutor(2);
406 final CountDownLatch threadStarted = new CountDownLatch(1);
407 final CountDownLatch threadProceed = new CountDownLatch(1);
408 final CountDownLatch threadDone = new CountDownLatch(1);
409 try {
410 assertEquals(0, p.getCompletedTaskCount());
411 p.execute(new CheckedRunnable() {
412 public void realRun() throws InterruptedException {
413 threadStarted.countDown();
414 assertEquals(0, p.getCompletedTaskCount());
415 threadProceed.await();
416 threadDone.countDown();
417 }});
418 await(threadStarted);
419 assertEquals(0, p.getCompletedTaskCount());
420 threadProceed.countDown();
421 threadDone.await();
422 long startTime = System.nanoTime();
423 while (p.getCompletedTaskCount() != 1) {
424 if (millisElapsedSince(startTime) > LONG_DELAY_MS)
425 fail("timed out");
426 Thread.yield();
427 }
428 } finally {
429 joinPool(p);
430 }
431 }
432
433 /**
434 * getCorePoolSize returns size given in constructor if not otherwise set
435 */
436 public void testGetCorePoolSize() {
437 CustomExecutor p = new CustomExecutor(1);
438 assertEquals(1, p.getCorePoolSize());
439 joinPool(p);
440 }
441
442 /**
443 * getLargestPoolSize increases, but doesn't overestimate, when
444 * multiple threads active
445 */
446 public void testGetLargestPoolSize() throws InterruptedException {
447 final int THREADS = 3;
448 final ThreadPoolExecutor p = new CustomExecutor(THREADS);
449 final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
450 final CountDownLatch done = new CountDownLatch(1);
451 try {
452 assertEquals(0, p.getLargestPoolSize());
453 for (int i = 0; i < THREADS; i++)
454 p.execute(new CheckedRunnable() {
455 public void realRun() throws InterruptedException {
456 threadsStarted.countDown();
457 done.await();
458 assertEquals(THREADS, p.getLargestPoolSize());
459 }});
460 assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
461 assertEquals(THREADS, p.getLargestPoolSize());
462 } finally {
463 done.countDown();
464 joinPool(p);
465 assertEquals(THREADS, p.getLargestPoolSize());
466 }
467 }
468
469 /**
470 * getPoolSize increases, but doesn't overestimate, when threads
471 * become active
472 */
473 public void testGetPoolSize() throws InterruptedException {
474 final ThreadPoolExecutor p = new CustomExecutor(1);
475 final CountDownLatch threadStarted = new CountDownLatch(1);
476 final CountDownLatch done = new CountDownLatch(1);
477 try {
478 assertEquals(0, p.getPoolSize());
479 p.execute(new CheckedRunnable() {
480 public void realRun() throws InterruptedException {
481 threadStarted.countDown();
482 assertEquals(1, p.getPoolSize());
483 done.await();
484 }});
485 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
486 assertEquals(1, p.getPoolSize());
487 } finally {
488 done.countDown();
489 joinPool(p);
490 }
491 }
492
493 /**
494 * getTaskCount increases, but doesn't overestimate, when tasks
495 * submitted
496 */
497 public void testGetTaskCount() throws InterruptedException {
498 final ThreadPoolExecutor p = new CustomExecutor(1);
499 final CountDownLatch threadStarted = new CountDownLatch(1);
500 final CountDownLatch done = new CountDownLatch(1);
501 final int TASKS = 5;
502 try {
503 assertEquals(0, p.getTaskCount());
504 for (int i = 0; i < TASKS; i++)
505 p.execute(new CheckedRunnable() {
506 public void realRun() throws InterruptedException {
507 threadStarted.countDown();
508 done.await();
509 }});
510 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
511 assertEquals(TASKS, p.getTaskCount());
512 } finally {
513 done.countDown();
514 joinPool(p);
515 }
516 }
517
518 /**
519 * getThreadFactory returns factory in constructor if not set
520 */
521 public void testGetThreadFactory() {
522 ThreadFactory tf = new SimpleThreadFactory();
523 CustomExecutor p = new CustomExecutor(1, tf);
524 assertSame(tf, p.getThreadFactory());
525 joinPool(p);
526 }
527
528 /**
529 * setThreadFactory sets the thread factory returned by getThreadFactory
530 */
531 public void testSetThreadFactory() {
532 ThreadFactory tf = new SimpleThreadFactory();
533 CustomExecutor p = new CustomExecutor(1);
534 p.setThreadFactory(tf);
535 assertSame(tf, p.getThreadFactory());
536 joinPool(p);
537 }
538
539 /**
540 * setThreadFactory(null) throws NPE
541 */
542 public void testSetThreadFactoryNull() {
543 CustomExecutor p = new CustomExecutor(1);
544 try {
545 p.setThreadFactory(null);
546 shouldThrow();
547 } catch (NullPointerException success) {
548 } finally {
549 joinPool(p);
550 }
551 }
552
553 /**
554 * isShutdown is false before shutdown, true after
555 */
556 public void testIsShutdown() {
557 CustomExecutor p = new CustomExecutor(1);
558 try {
559 assertFalse(p.isShutdown());
560 }
561 finally {
562 try { p.shutdown(); } catch (SecurityException ok) { return; }
563 }
564 assertTrue(p.isShutdown());
565 }
566
567 /**
568 * isTerminated is false before termination, true after
569 */
570 public void testIsTerminated() throws InterruptedException {
571 final ThreadPoolExecutor p = new CustomExecutor(1);
572 final CountDownLatch threadStarted = new CountDownLatch(1);
573 final CountDownLatch done = new CountDownLatch(1);
574 assertFalse(p.isTerminated());
575 try {
576 p.execute(new CheckedRunnable() {
577 public void realRun() throws InterruptedException {
578 assertFalse(p.isTerminated());
579 threadStarted.countDown();
580 done.await();
581 }});
582 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
583 assertFalse(p.isTerminating());
584 done.countDown();
585 } finally {
586 try { p.shutdown(); } catch (SecurityException ok) { return; }
587 }
588 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
589 assertTrue(p.isTerminated());
590 }
591
592 /**
593 * isTerminating is not true when running or when terminated
594 */
595 public void testIsTerminating() throws InterruptedException {
596 final ThreadPoolExecutor p = new CustomExecutor(1);
597 final CountDownLatch threadStarted = new CountDownLatch(1);
598 final CountDownLatch done = new CountDownLatch(1);
599 try {
600 assertFalse(p.isTerminating());
601 p.execute(new CheckedRunnable() {
602 public void realRun() throws InterruptedException {
603 assertFalse(p.isTerminating());
604 threadStarted.countDown();
605 done.await();
606 }});
607 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
608 assertFalse(p.isTerminating());
609 done.countDown();
610 } finally {
611 try { p.shutdown(); } catch (SecurityException ok) { return; }
612 }
613 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
614 assertTrue(p.isTerminated());
615 assertFalse(p.isTerminating());
616 }
617
618 /**
619 * getQueue returns the work queue, which contains queued tasks
620 */
621 public void testGetQueue() throws InterruptedException {
622 ScheduledThreadPoolExecutor p = new CustomExecutor(1);
623 final CountDownLatch threadStarted = new CountDownLatch(1);
624 final CountDownLatch done = new CountDownLatch(1);
625 try {
626 ScheduledFuture[] tasks = new ScheduledFuture[5];
627 for (int i = 0; i < tasks.length; i++) {
628 Runnable r = new CheckedRunnable() {
629 public void realRun() throws InterruptedException {
630 threadStarted.countDown();
631 done.await();
632 }};
633 tasks[i] = p.schedule(r, 1, MILLISECONDS);
634 }
635 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
636 BlockingQueue<Runnable> q = p.getQueue();
637 assertTrue(q.contains(tasks[tasks.length - 1]));
638 assertFalse(q.contains(tasks[0]));
639 } finally {
640 done.countDown();
641 joinPool(p);
642 }
643 }
644
645 /**
646 * remove(task) removes queued task, and fails to remove active task
647 */
648 public void testRemove() throws InterruptedException {
649 final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
650 ScheduledFuture[] tasks = new ScheduledFuture[5];
651 final CountDownLatch threadStarted = new CountDownLatch(1);
652 final CountDownLatch done = new CountDownLatch(1);
653 try {
654 for (int i = 0; i < tasks.length; i++) {
655 Runnable r = new CheckedRunnable() {
656 public void realRun() throws InterruptedException {
657 threadStarted.countDown();
658 done.await();
659 }};
660 tasks[i] = p.schedule(r, 1, MILLISECONDS);
661 }
662 assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
663 BlockingQueue<Runnable> q = p.getQueue();
664 assertFalse(p.remove((Runnable)tasks[0]));
665 assertTrue(q.contains((Runnable)tasks[4]));
666 assertTrue(q.contains((Runnable)tasks[3]));
667 assertTrue(p.remove((Runnable)tasks[4]));
668 assertFalse(p.remove((Runnable)tasks[4]));
669 assertFalse(q.contains((Runnable)tasks[4]));
670 assertTrue(q.contains((Runnable)tasks[3]));
671 assertTrue(p.remove((Runnable)tasks[3]));
672 assertFalse(q.contains((Runnable)tasks[3]));
673 } finally {
674 done.countDown();
675 joinPool(p);
676 }
677 }
678
679 /**
680 * purge removes cancelled tasks from the queue
681 */
682 public void testPurge() throws InterruptedException {
683 CustomExecutor p = new CustomExecutor(1);
684 ScheduledFuture[] tasks = new ScheduledFuture[5];
685 for (int i = 0; i < tasks.length; i++)
686 tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
687 LONG_DELAY_MS, MILLISECONDS);
688 try {
689 int max = tasks.length;
690 if (tasks[4].cancel(true)) --max;
691 if (tasks[3].cancel(true)) --max;
692 // There must eventually be an interference-free point at
693 // which purge will not fail. (At worst, when queue is empty.)
694 long startTime = System.nanoTime();
695 do {
696 p.purge();
697 long count = p.getTaskCount();
698 if (count == max)
699 return;
700 } while (millisElapsedSince(startTime) < MEDIUM_DELAY_MS);
701 fail("Purge failed to remove cancelled tasks");
702 } finally {
703 for (ScheduledFuture task : tasks)
704 task.cancel(true);
705 joinPool(p);
706 }
707 }
708
709 /**
710 * shutdownNow returns a list containing tasks that were not run,
711 * and those tasks are drained from the queue
712 */
713 public void testShutdownNow() throws InterruptedException {
714 final int poolSize = 2;
715 final int count = 5;
716 final AtomicInteger ran = new AtomicInteger(0);
717 final CustomExecutor p = new CustomExecutor(poolSize);
718 CountDownLatch threadsStarted = new CountDownLatch(poolSize);
719 CheckedRunnable waiter = new CheckedRunnable() { public void realRun() {
720 threadsStarted.countDown();
721 try {
722 MILLISECONDS.sleep(2 * LONG_DELAY_MS);
723 } catch (InterruptedException success) {}
724 ran.getAndIncrement();
725 }};
726 for (int i = 0; i < count; i++)
727 p.execute(waiter);
728 assertTrue(threadsStarted.await(LONG_DELAY_MS, MILLISECONDS));
729 assertEquals(poolSize, p.getActiveCount());
730 assertEquals(0, p.getCompletedTaskCount());
731 final List<Runnable> queuedTasks;
732 try {
733 queuedTasks = p.shutdownNow();
734 } catch (SecurityException ok) {
735 return; // Allowed in case test doesn't have privs
736 }
737 assertTrue(p.isShutdown());
738 assertTrue(p.getQueue().isEmpty());
739 assertEquals(count - poolSize, queuedTasks.size());
740 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
741 assertTrue(p.isTerminated());
742 assertEquals(poolSize, ran.get());
743 assertEquals(poolSize, p.getCompletedTaskCount());
744 }
745
746 /**
747 * shutdownNow returns a list containing tasks that were not run,
748 * and those tasks are drained from the queue
749 */
750 public void testShutdownNow_delayedTasks() throws InterruptedException {
751 CustomExecutor p = new CustomExecutor(1);
752 List<ScheduledFuture> tasks = new ArrayList<>();
753 for (int i = 0; i < 3; i++) {
754 Runnable r = new NoOpRunnable();
755 tasks.add(p.schedule(r, 9, SECONDS));
756 tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS));
757 tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS));
758 }
759 if (testImplementationDetails)
760 assertEquals(new HashSet(tasks), new HashSet(p.getQueue()));
761 final List<Runnable> queuedTasks;
762 try {
763 queuedTasks = p.shutdownNow();
764 } catch (SecurityException ok) {
765 return; // Allowed in case test doesn't have privs
766 }
767 assertTrue(p.isShutdown());
768 assertTrue(p.getQueue().isEmpty());
769 if (testImplementationDetails)
770 assertEquals(new HashSet(tasks), new HashSet(queuedTasks));
771 assertEquals(tasks.size(), queuedTasks.size());
772 for (ScheduledFuture task : tasks) {
773 assertFalse(((CustomTask)task).ran);
774 assertFalse(task.isDone());
775 assertFalse(task.isCancelled());
776 }
777 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
778 assertTrue(p.isTerminated());
779 }
780
781 /**
782 * In default setting, shutdown cancels periodic but not delayed
783 * tasks at shutdown
784 */
785 public void testShutdown1() throws InterruptedException {
786 CustomExecutor p = new CustomExecutor(1);
787 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
788 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
789
790 ScheduledFuture[] tasks = new ScheduledFuture[5];
791 for (int i = 0; i < tasks.length; i++)
792 tasks[i] = p.schedule(new NoOpRunnable(),
793 SHORT_DELAY_MS, MILLISECONDS);
794 try { p.shutdown(); } catch (SecurityException ok) { return; }
795 BlockingQueue<Runnable> q = p.getQueue();
796 for (ScheduledFuture task : tasks) {
797 assertFalse(task.isDone());
798 assertFalse(task.isCancelled());
799 assertTrue(q.contains(task));
800 }
801 assertTrue(p.isShutdown());
802 assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
803 assertTrue(p.isTerminated());
804 for (ScheduledFuture task : tasks) {
805 assertTrue(task.isDone());
806 assertFalse(task.isCancelled());
807 }
808 }
809
810 /**
811 * If setExecuteExistingDelayedTasksAfterShutdownPolicy is false,
812 * delayed tasks are cancelled at shutdown
813 */
814 public void testShutdown2() throws InterruptedException {
815 CustomExecutor p = new CustomExecutor(1);
816 p.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
817 assertFalse(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
818 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
819 ScheduledFuture[] tasks = new ScheduledFuture[5];
820 for (int i = 0; i < tasks.length; i++)
821 tasks[i] = p.schedule(new NoOpRunnable(),
822 SHORT_DELAY_MS, MILLISECONDS);
823 BlockingQueue q = p.getQueue();
824 assertEquals(tasks.length, q.size());
825 try { p.shutdown(); } catch (SecurityException ok) { return; }
826 assertTrue(p.isShutdown());
827 assertTrue(q.isEmpty());
828 assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
829 assertTrue(p.isTerminated());
830 for (ScheduledFuture task : tasks) {
831 assertTrue(task.isDone());
832 assertTrue(task.isCancelled());
833 }
834 }
835
836 /**
837 * If setContinueExistingPeriodicTasksAfterShutdownPolicy is set false,
838 * periodic tasks are cancelled at shutdown
839 */
840 public void testShutdown3() throws InterruptedException {
841 CustomExecutor p = new CustomExecutor(1);
842 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
843 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
844 p.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
845 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
846 assertFalse(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
847 long initialDelay = LONG_DELAY_MS;
848 ScheduledFuture task =
849 p.scheduleAtFixedRate(new NoOpRunnable(), initialDelay,
850 5, MILLISECONDS);
851 try { p.shutdown(); } catch (SecurityException ok) { return; }
852 assertTrue(p.isShutdown());
853 assertTrue(p.getQueue().isEmpty());
854 assertTrue(task.isDone());
855 assertTrue(task.isCancelled());
856 joinPool(p);
857 }
858
859 /**
860 * if setContinueExistingPeriodicTasksAfterShutdownPolicy is true,
861 * periodic tasks are not cancelled at shutdown
862 */
863 public void testShutdown4() throws InterruptedException {
864 CustomExecutor p = new CustomExecutor(1);
865 final CountDownLatch counter = new CountDownLatch(2);
866 try {
867 p.setContinueExistingPeriodicTasksAfterShutdownPolicy(true);
868 assertTrue(p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
869 assertTrue(p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
870 final Runnable r = new CheckedRunnable() {
871 public void realRun() {
872 counter.countDown();
873 }};
874 ScheduledFuture task =
875 p.scheduleAtFixedRate(r, 1, 1, MILLISECONDS);
876 assertFalse(task.isDone());
877 assertFalse(task.isCancelled());
878 try { p.shutdown(); } catch (SecurityException ok) { return; }
879 assertFalse(task.isCancelled());
880 assertFalse(p.isTerminated());
881 assertTrue(p.isShutdown());
882 assertTrue(counter.await(SMALL_DELAY_MS, MILLISECONDS));
883 assertFalse(task.isCancelled());
884 assertTrue(task.cancel(false));
885 assertTrue(task.isDone());
886 assertTrue(task.isCancelled());
887 assertTrue(p.awaitTermination(SMALL_DELAY_MS, MILLISECONDS));
888 assertTrue(p.isTerminated());
889 }
890 finally {
891 joinPool(p);
892 }
893 }
894
895 /**
896 * completed submit of callable returns result
897 */
898 public void testSubmitCallable() throws Exception {
899 ExecutorService e = new CustomExecutor(2);
900 try {
901 Future<String> future = e.submit(new StringTask());
902 String result = future.get();
903 assertSame(TEST_STRING, result);
904 } finally {
905 joinPool(e);
906 }
907 }
908
909 /**
910 * completed submit of runnable returns successfully
911 */
912 public void testSubmitRunnable() throws Exception {
913 ExecutorService e = new CustomExecutor(2);
914 try {
915 Future<?> future = e.submit(new NoOpRunnable());
916 future.get();
917 assertTrue(future.isDone());
918 } finally {
919 joinPool(e);
920 }
921 }
922
923 /**
924 * completed submit of (runnable, result) returns result
925 */
926 public void testSubmitRunnable2() throws Exception {
927 ExecutorService e = new CustomExecutor(2);
928 try {
929 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
930 String result = future.get();
931 assertSame(TEST_STRING, result);
932 } finally {
933 joinPool(e);
934 }
935 }
936
937 /**
938 * invokeAny(null) throws NPE
939 */
940 public void testInvokeAny1() throws Exception {
941 ExecutorService e = new CustomExecutor(2);
942 try {
943 e.invokeAny(null);
944 shouldThrow();
945 } catch (NullPointerException success) {
946 } finally {
947 joinPool(e);
948 }
949 }
950
951 /**
952 * invokeAny(empty collection) throws IAE
953 */
954 public void testInvokeAny2() throws Exception {
955 ExecutorService e = new CustomExecutor(2);
956 try {
957 e.invokeAny(new ArrayList<Callable<String>>());
958 shouldThrow();
959 } catch (IllegalArgumentException success) {
960 } finally {
961 joinPool(e);
962 }
963 }
964
965 /**
966 * invokeAny(c) throws NPE if c has null elements
967 */
968 public void testInvokeAny3() throws Exception {
969 CountDownLatch latch = new CountDownLatch(1);
970 ExecutorService e = new CustomExecutor(2);
971 List<Callable<String>> l = new ArrayList<Callable<String>>();
972 l.add(latchAwaitingStringTask(latch));
973 l.add(null);
974 try {
975 e.invokeAny(l);
976 shouldThrow();
977 } catch (NullPointerException success) {
978 } finally {
979 latch.countDown();
980 joinPool(e);
981 }
982 }
983
984 /**
985 * invokeAny(c) throws ExecutionException if no task completes
986 */
987 public void testInvokeAny4() throws Exception {
988 ExecutorService e = new CustomExecutor(2);
989 List<Callable<String>> l = new ArrayList<Callable<String>>();
990 l.add(new NPETask());
991 try {
992 e.invokeAny(l);
993 shouldThrow();
994 } catch (ExecutionException success) {
995 assertTrue(success.getCause() instanceof NullPointerException);
996 } finally {
997 joinPool(e);
998 }
999 }
1000
1001 /**
1002 * invokeAny(c) returns result of some task
1003 */
1004 public void testInvokeAny5() throws Exception {
1005 ExecutorService e = new CustomExecutor(2);
1006 try {
1007 List<Callable<String>> l = new ArrayList<Callable<String>>();
1008 l.add(new StringTask());
1009 l.add(new StringTask());
1010 String result = e.invokeAny(l);
1011 assertSame(TEST_STRING, result);
1012 } finally {
1013 joinPool(e);
1014 }
1015 }
1016
1017 /**
1018 * invokeAll(null) throws NPE
1019 */
1020 public void testInvokeAll1() throws Exception {
1021 ExecutorService e = new CustomExecutor(2);
1022 try {
1023 e.invokeAll(null);
1024 shouldThrow();
1025 } catch (NullPointerException success) {
1026 } finally {
1027 joinPool(e);
1028 }
1029 }
1030
1031 /**
1032 * invokeAll(empty collection) returns empty collection
1033 */
1034 public void testInvokeAll2() throws Exception {
1035 ExecutorService e = new CustomExecutor(2);
1036 try {
1037 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
1038 assertTrue(r.isEmpty());
1039 } finally {
1040 joinPool(e);
1041 }
1042 }
1043
1044 /**
1045 * invokeAll(c) throws NPE if c has null elements
1046 */
1047 public void testInvokeAll3() throws Exception {
1048 ExecutorService e = new CustomExecutor(2);
1049 List<Callable<String>> l = new ArrayList<Callable<String>>();
1050 l.add(new StringTask());
1051 l.add(null);
1052 try {
1053 e.invokeAll(l);
1054 shouldThrow();
1055 } catch (NullPointerException success) {
1056 } finally {
1057 joinPool(e);
1058 }
1059 }
1060
1061 /**
1062 * get of invokeAll(c) throws exception on failed task
1063 */
1064 public void testInvokeAll4() throws Exception {
1065 ExecutorService e = new CustomExecutor(2);
1066 List<Callable<String>> l = new ArrayList<Callable<String>>();
1067 l.add(new NPETask());
1068 List<Future<String>> futures = e.invokeAll(l);
1069 assertEquals(1, futures.size());
1070 try {
1071 futures.get(0).get();
1072 shouldThrow();
1073 } catch (ExecutionException success) {
1074 assertTrue(success.getCause() instanceof NullPointerException);
1075 } finally {
1076 joinPool(e);
1077 }
1078 }
1079
1080 /**
1081 * invokeAll(c) returns results of all completed tasks
1082 */
1083 public void testInvokeAll5() throws Exception {
1084 ExecutorService e = new CustomExecutor(2);
1085 try {
1086 List<Callable<String>> l = new ArrayList<Callable<String>>();
1087 l.add(new StringTask());
1088 l.add(new StringTask());
1089 List<Future<String>> futures = e.invokeAll(l);
1090 assertEquals(2, futures.size());
1091 for (Future<String> future : futures)
1092 assertSame(TEST_STRING, future.get());
1093 } finally {
1094 joinPool(e);
1095 }
1096 }
1097
1098 /**
1099 * timed invokeAny(null) throws NPE
1100 */
1101 public void testTimedInvokeAny1() throws Exception {
1102 ExecutorService e = new CustomExecutor(2);
1103 try {
1104 e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS);
1105 shouldThrow();
1106 } catch (NullPointerException success) {
1107 } finally {
1108 joinPool(e);
1109 }
1110 }
1111
1112 /**
1113 * timed invokeAny(,,null) throws NPE
1114 */
1115 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
1116 ExecutorService e = new CustomExecutor(2);
1117 List<Callable<String>> l = new ArrayList<Callable<String>>();
1118 l.add(new StringTask());
1119 try {
1120 e.invokeAny(l, MEDIUM_DELAY_MS, null);
1121 shouldThrow();
1122 } catch (NullPointerException success) {
1123 } finally {
1124 joinPool(e);
1125 }
1126 }
1127
1128 /**
1129 * timed invokeAny(empty collection) throws IAE
1130 */
1131 public void testTimedInvokeAny2() throws Exception {
1132 ExecutorService e = new CustomExecutor(2);
1133 try {
1134 e.invokeAny(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1135 shouldThrow();
1136 } catch (IllegalArgumentException success) {
1137 } finally {
1138 joinPool(e);
1139 }
1140 }
1141
1142 /**
1143 * timed invokeAny(c) throws NPE if c has null elements
1144 */
1145 public void testTimedInvokeAny3() throws Exception {
1146 CountDownLatch latch = new CountDownLatch(1);
1147 ExecutorService e = new CustomExecutor(2);
1148 List<Callable<String>> l = new ArrayList<Callable<String>>();
1149 l.add(latchAwaitingStringTask(latch));
1150 l.add(null);
1151 try {
1152 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1153 shouldThrow();
1154 } catch (NullPointerException success) {
1155 } finally {
1156 latch.countDown();
1157 joinPool(e);
1158 }
1159 }
1160
1161 /**
1162 * timed invokeAny(c) throws ExecutionException if no task completes
1163 */
1164 public void testTimedInvokeAny4() throws Exception {
1165 ExecutorService e = new CustomExecutor(2);
1166 List<Callable<String>> l = new ArrayList<Callable<String>>();
1167 l.add(new NPETask());
1168 try {
1169 e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1170 shouldThrow();
1171 } catch (ExecutionException success) {
1172 assertTrue(success.getCause() instanceof NullPointerException);
1173 } finally {
1174 joinPool(e);
1175 }
1176 }
1177
1178 /**
1179 * timed invokeAny(c) returns result of some task
1180 */
1181 public void testTimedInvokeAny5() throws Exception {
1182 ExecutorService e = new CustomExecutor(2);
1183 try {
1184 List<Callable<String>> l = new ArrayList<Callable<String>>();
1185 l.add(new StringTask());
1186 l.add(new StringTask());
1187 String result = e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS);
1188 assertSame(TEST_STRING, result);
1189 } finally {
1190 joinPool(e);
1191 }
1192 }
1193
1194 /**
1195 * timed invokeAll(null) throws NPE
1196 */
1197 public void testTimedInvokeAll1() throws Exception {
1198 ExecutorService e = new CustomExecutor(2);
1199 try {
1200 e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS);
1201 shouldThrow();
1202 } catch (NullPointerException success) {
1203 } finally {
1204 joinPool(e);
1205 }
1206 }
1207
1208 /**
1209 * timed invokeAll(,,null) throws NPE
1210 */
1211 public void testTimedInvokeAllNullTimeUnit() throws Exception {
1212 ExecutorService e = new CustomExecutor(2);
1213 List<Callable<String>> l = new ArrayList<Callable<String>>();
1214 l.add(new StringTask());
1215 try {
1216 e.invokeAll(l, MEDIUM_DELAY_MS, null);
1217 shouldThrow();
1218 } catch (NullPointerException success) {
1219 } finally {
1220 joinPool(e);
1221 }
1222 }
1223
1224 /**
1225 * timed invokeAll(empty collection) returns empty collection
1226 */
1227 public void testTimedInvokeAll2() throws Exception {
1228 ExecutorService e = new CustomExecutor(2);
1229 try {
1230 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>(), MEDIUM_DELAY_MS, MILLISECONDS);
1231 assertTrue(r.isEmpty());
1232 } finally {
1233 joinPool(e);
1234 }
1235 }
1236
1237 /**
1238 * timed invokeAll(c) throws NPE if c has null elements
1239 */
1240 public void testTimedInvokeAll3() throws Exception {
1241 ExecutorService e = new CustomExecutor(2);
1242 List<Callable<String>> l = new ArrayList<Callable<String>>();
1243 l.add(new StringTask());
1244 l.add(null);
1245 try {
1246 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1247 shouldThrow();
1248 } catch (NullPointerException success) {
1249 } finally {
1250 joinPool(e);
1251 }
1252 }
1253
1254 /**
1255 * get of element of invokeAll(c) throws exception on failed task
1256 */
1257 public void testTimedInvokeAll4() throws Exception {
1258 ExecutorService e = new CustomExecutor(2);
1259 List<Callable<String>> l = new ArrayList<Callable<String>>();
1260 l.add(new NPETask());
1261 List<Future<String>> futures =
1262 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1263 assertEquals(1, futures.size());
1264 try {
1265 futures.get(0).get();
1266 shouldThrow();
1267 } catch (ExecutionException success) {
1268 assertTrue(success.getCause() instanceof NullPointerException);
1269 } finally {
1270 joinPool(e);
1271 }
1272 }
1273
1274 /**
1275 * timed invokeAll(c) returns results of all completed tasks
1276 */
1277 public void testTimedInvokeAll5() throws Exception {
1278 ExecutorService e = new CustomExecutor(2);
1279 try {
1280 List<Callable<String>> l = new ArrayList<Callable<String>>();
1281 l.add(new StringTask());
1282 l.add(new StringTask());
1283 List<Future<String>> futures =
1284 e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1285 assertEquals(2, futures.size());
1286 for (Future<String> future : futures)
1287 assertSame(TEST_STRING, future.get());
1288 } finally {
1289 joinPool(e);
1290 }
1291 }
1292
1293 /**
1294 * timed invokeAll(c) cancels tasks not completed by timeout
1295 */
1296 public void testTimedInvokeAll6() throws Exception {
1297 ExecutorService e = new CustomExecutor(2);
1298 try {
1299 for (long timeout = timeoutMillis();;) {
1300 List<Callable<String>> tasks = new ArrayList<>();
1301 tasks.add(new StringTask("0"));
1302 tasks.add(Executors.callable(new LongPossiblyInterruptedRunnable(), TEST_STRING));
1303 tasks.add(new StringTask("2"));
1304 long startTime = System.nanoTime();
1305 List<Future<String>> futures =
1306 e.invokeAll(tasks, timeout, MILLISECONDS);
1307 assertEquals(tasks.size(), futures.size());
1308 assertTrue(millisElapsedSince(startTime) >= timeout);
1309 for (Future future : futures)
1310 assertTrue(future.isDone());
1311 assertTrue(futures.get(1).isCancelled());
1312 try {
1313 assertEquals("0", futures.get(0).get());
1314 assertEquals("2", futures.get(2).get());
1315 break;
1316 } catch (CancellationException retryWithLongerTimeout) {
1317 timeout *= 2;
1318 if (timeout >= LONG_DELAY_MS / 2)
1319 fail("expected exactly one task to be cancelled");
1320 }
1321 }
1322 } finally {
1323 joinPool(e);
1324 }
1325 }
1326
1327 }