ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorTest.java
Revision: 1.94
Committed: Mon May 29 22:44:27 2017 UTC (6 years, 11 months ago) by jsr166
Branch: MAIN
Changes since 1.93: +28 -20 lines
Log Message:
more timeout handling rework; remove most uses of MEDIUM_DELAY_MS; randomize timeouts and TimeUnits; write out IAE and ISE

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