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