ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorTest.java
Revision: 1.72
Committed: Tue Oct 6 05:30:44 2015 UTC (8 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.71: +6 -6 lines
Log Message:
improve test diagnosability

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