ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorTest.java
Revision: 1.96
Committed: Mon Jan 8 02:04:15 2018 UTC (6 years, 3 months ago) by jsr166
Branch: MAIN
Changes since 1.95: +2 -2 lines
Log Message:
use method reference

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