blob: 81f73700a4896b706214ea49b260ff0f33298ebe [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
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
9package jsr166;
10
Calin Juravle8f0d92b2013-08-01 17:26:00 +010011import static java.util.concurrent.TimeUnit.MILLISECONDS;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000012import static java.util.concurrent.TimeUnit.NANOSECONDS;
13import static java.util.concurrent.TimeUnit.SECONDS;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010014
15import java.util.ArrayList;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000016import java.util.HashSet;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010017import java.util.List;
18import java.util.concurrent.BlockingQueue;
19import java.util.concurrent.Callable;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000020import java.util.concurrent.CancellationException;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010021import java.util.concurrent.CountDownLatch;
22import java.util.concurrent.ExecutionException;
23import java.util.concurrent.Executors;
24import java.util.concurrent.ExecutorService;
25import java.util.concurrent.Future;
26import java.util.concurrent.RejectedExecutionException;
27import java.util.concurrent.ScheduledFuture;
28import java.util.concurrent.ScheduledThreadPoolExecutor;
29import java.util.concurrent.ThreadFactory;
30import java.util.concurrent.ThreadPoolExecutor;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000031import java.util.concurrent.atomic.AtomicBoolean;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010032import java.util.concurrent.atomic.AtomicInteger;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000033import java.util.concurrent.atomic.AtomicLong;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010034
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010035import junit.framework.Test;
36import junit.framework.TestSuite;
37
Calin Juravle8f0d92b2013-08-01 17:26:00 +010038public class ScheduledExecutorTest extends JSR166TestCase {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010039 // 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() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000046 // return new TestSuite(ScheduledExecutorTest.class);
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010047 // }
Calin Juravle8f0d92b2013-08-01 17:26:00 +010048
49 /**
50 * execute successfully executes a runnable
51 */
52 public void testExecute() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000053 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(); }};
Calin Juravle8f0d92b2013-08-01 17:26:00 +010058 p.execute(task);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000059 assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
Calin Juravle8f0d92b2013-08-01 17:26:00 +010060 }
61 }
62
63 /**
64 * delayed schedule of callable successfully executes after delay
65 */
66 public void testSchedule1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000067 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +010071 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));
Calin Juravle8f0d92b2013-08-01 17:26:00 +010081 }
82 }
83
84 /**
85 * delayed schedule of runnable successfully executes after delay
86 */
87 public void testSchedule3() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000088 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +010092 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());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100101 }
102 }
103
104 /**
105 * scheduleAtFixedRate executes runnable after given initial delay
106 */
107 public void testSchedule4() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000108 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100112 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100123 }
124 }
125
126 /**
127 * scheduleWithFixedDelay executes runnable after given initial delay
128 */
129 public void testSchedule5() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000130 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100134 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100145 }
146 }
147
148 static class RunnableCounter implements Runnable {
149 AtomicInteger count = new AtomicInteger(0);
150 public void run() { count.getAndIncrement(); }
151 }
152
153 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000154 * scheduleAtFixedRate executes series of tasks at given rate.
155 * Eventually, it must hold that:
156 * cycles - 1 <= elapsedMillis/delay < cycles
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100157 */
158 public void testFixedRateSequence() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000159 final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
160 try (PoolCleaner cleaner = cleaner(p)) {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100161 for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000162 final long startTime = System.nanoTime();
163 final int cycles = 8;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100164 final CountDownLatch done = new CountDownLatch(cycles);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000165 final Runnable task = new CheckedRunnable() {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100166 public void realRun() { done.countDown(); }};
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000167 final ScheduledFuture periodicTask =
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100168 p.scheduleAtFixedRate(task, 0, delay, MILLISECONDS);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000169 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)
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100175 return;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000176 // else retry with longer delay
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100177 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000178 fail("unexpected execution rate");
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100179 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100180 }
181
182 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000183 * 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.
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100186 */
187 public void testFixedDelaySequence() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000188 final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
189 try (PoolCleaner cleaner = cleaner(p)) {
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100190 for (int delay = 1; delay <= LONG_DELAY_MS; delay *= 3) {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000191 final long startTime = System.nanoTime();
192 final AtomicLong previous = new AtomicLong(startTime);
193 final AtomicBoolean tryLongerDelay = new AtomicBoolean(false);
194 final int cycles = 8;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100195 final CountDownLatch done = new CountDownLatch(cycles);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000196 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 =
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100214 p.scheduleWithFixedDelay(task, 0, delay, MILLISECONDS);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000215 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())
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100221 return;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000222 // else retry with longer delay
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100223 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000224 fail("unexpected execution rate");
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100225 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100226 }
227
228 /**
229 * execute(null) throws NPE
230 */
231 public void testExecuteNull() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000232 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 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100239 }
240
241 /**
242 * schedule(null) throws NPE
243 */
244 public void testScheduleNull() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000245 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 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100253 }
254
255 /**
256 * execute throws RejectedExecutionException if shutdown
257 */
258 public void testSchedule1_RejectedExecutionException() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000259 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100268 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100269 }
270
271 /**
272 * schedule throws RejectedExecutionException if shutdown
273 */
274 public void testSchedule2_RejectedExecutionException() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000275 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100284 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100285 }
286
287 /**
288 * schedule callable throws RejectedExecutionException if shutdown
289 */
290 public void testSchedule3_RejectedExecutionException() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000291 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100300 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100301 }
302
303 /**
304 * scheduleAtFixedRate throws RejectedExecutionException if shutdown
305 */
306 public void testScheduleAtFixedRate1_RejectedExecutionException() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000307 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100316 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100317 }
318
319 /**
320 * scheduleWithFixedDelay throws RejectedExecutionException if shutdown
321 */
322 public void testScheduleWithFixedDelay1_RejectedExecutionException() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000323 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100332 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100333 }
334
335 /**
336 * getActiveCount increases but doesn't overestimate, when a
337 * thread becomes active
338 */
339 public void testGetActiveCount() throws InterruptedException {
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000340 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000341 final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(2);
342 try (PoolCleaner cleaner = cleaner(p, done)) {
343 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100344 assertEquals(0, p.getActiveCount());
345 p.execute(new CheckedRunnable() {
346 public void realRun() throws InterruptedException {
347 threadStarted.countDown();
348 assertEquals(1, p.getActiveCount());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000349 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100350 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000351 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100352 assertEquals(1, p.getActiveCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100353 }
354 }
355
356 /**
357 * getCompletedTaskCount increases, but doesn't overestimate,
358 * when tasks complete
359 */
360 public void testGetCompletedTaskCount() throws InterruptedException {
361 final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(2);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000362 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100366 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 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100384 }
385 }
386
387 /**
388 * getCorePoolSize returns size given in constructor if not otherwise set
389 */
390 public void testGetCorePoolSize() throws InterruptedException {
391 ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000392 try (PoolCleaner cleaner = cleaner(p)) {
393 assertEquals(1, p.getCorePoolSize());
394 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100395 }
396
397 /**
398 * getLargestPoolSize increases, but doesn't overestimate, when
399 * multiple threads active
400 */
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);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000406 try (PoolCleaner cleaner = cleaner(p, done)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100407 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();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000412 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100413 assertEquals(THREADS, p.getLargestPoolSize());
414 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000415 await(threadsStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100416 assertEquals(THREADS, p.getLargestPoolSize());
417 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000418 assertEquals(THREADS, p.getLargestPoolSize());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100419 }
420
421 /**
422 * getPoolSize increases, but doesn't overestimate, when threads
423 * become active
424 */
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);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000429 try (PoolCleaner cleaner = cleaner(p, done)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100430 assertEquals(0, p.getPoolSize());
431 p.execute(new CheckedRunnable() {
432 public void realRun() throws InterruptedException {
433 threadStarted.countDown();
434 assertEquals(1, p.getPoolSize());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000435 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100436 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000437 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100438 assertEquals(1, p.getPoolSize());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100439 }
440 }
441
442 /**
443 * getTaskCount increases, but doesn't overestimate, when tasks
444 * submitted
445 */
446 public void testGetTaskCount() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000447 final int TASKS = 3;
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000448 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000449 final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
450 try (PoolCleaner cleaner = cleaner(p, done)) {
451 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100452 assertEquals(0, p.getTaskCount());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000453 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());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100464 p.execute(new CheckedRunnable() {
465 public void realRun() throws InterruptedException {
466 threadStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000467 assertEquals(1 + TASKS, p.getTaskCount());
468 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100469 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000470 }
471 assertEquals(1 + TASKS, p.getTaskCount());
472 assertEquals(0, p.getCompletedTaskCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100473 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000474 assertEquals(1 + TASKS, p.getTaskCount());
475 assertEquals(1 + TASKS, p.getCompletedTaskCount());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100476 }
477
478 /**
479 * getThreadFactory returns factory in constructor if not set
480 */
481 public void testGetThreadFactory() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000482 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 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100488 }
489
490 /**
491 * setThreadFactory sets the thread factory returned by getThreadFactory
492 */
493 public void testSetThreadFactory() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000494 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 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100500 }
501
502 /**
503 * setThreadFactory(null) throws NPE
504 */
505 public void testSetThreadFactoryNull() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000506 final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
507 try (PoolCleaner cleaner = cleaner(p)) {
508 try {
509 p.setThreadFactory(null);
510 shouldThrow();
511 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100512 }
513 }
514
515 /**
516 * isShutdown is false before shutdown, true after
517 */
518 public void testIsShutdown() {
519
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000520 final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100521 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 */
533 public void testIsTerminated() throws InterruptedException {
534 final ThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000535 try (PoolCleaner cleaner = cleaner(p)) {
536 final CountDownLatch threadStarted = new CountDownLatch(1);
537 final CountDownLatch done = new CountDownLatch(1);
538 assertFalse(p.isTerminated());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100539 p.execute(new CheckedRunnable() {
540 public void realRun() throws InterruptedException {
541 assertFalse(p.isTerminated());
542 threadStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000543 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100544 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000545 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100546 assertFalse(p.isTerminating());
547 done.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100548 try { p.shutdown(); } catch (SecurityException ok) { return; }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000549 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
550 assertTrue(p.isTerminated());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100551 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100552 }
553
554 /**
555 * isTerminating is not true when running or when terminated
556 */
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);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000561 try (PoolCleaner cleaner = cleaner(p)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100562 assertFalse(p.isTerminating());
563 p.execute(new CheckedRunnable() {
564 public void realRun() throws InterruptedException {
565 assertFalse(p.isTerminating());
566 threadStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000567 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100568 }});
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000569 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100570 assertFalse(p.isTerminating());
571 done.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100572 try { p.shutdown(); } catch (SecurityException ok) { return; }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000573 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
574 assertTrue(p.isTerminated());
575 assertFalse(p.isTerminating());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100576 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100577 }
578
579 /**
580 * getQueue returns the work queue, which contains queued tasks
581 */
582 public void testGetQueue() throws InterruptedException {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100583 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000584 final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
585 try (PoolCleaner cleaner = cleaner(p, done)) {
586 final CountDownLatch threadStarted = new CountDownLatch(1);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100587 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();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000592 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100593 }};
594 tasks[i] = p.schedule(r, 1, MILLISECONDS);
595 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000596 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100597 BlockingQueue<Runnable> q = p.getQueue();
598 assertTrue(q.contains(tasks[tasks.length - 1]));
599 assertFalse(q.contains(tasks[0]));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100600 }
601 }
602
603 /**
604 * remove(task) removes queued task, and fails to remove active task
605 */
606 public void testRemove() throws InterruptedException {
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000607 final CountDownLatch done = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000608 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100612 for (int i = 0; i < tasks.length; i++) {
613 Runnable r = new CheckedRunnable() {
614 public void realRun() throws InterruptedException {
615 threadStarted.countDown();
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000616 await(done);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100617 }};
618 tasks[i] = p.schedule(r, 1, MILLISECONDS);
619 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000620 await(threadStarted);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100621 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]));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100631 }
632 }
633
634 /**
635 * purge eventually removes cancelled tasks from the queue
636 */
637 public void testPurge() throws InterruptedException {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000638 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100647 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;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000658 } while (millisElapsedSince(startTime) < LONG_DELAY_MS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100659 fail("Purge failed to remove cancelled tasks");
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100660 }
661 }
662
663 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000664 * shutdownNow returns a list containing tasks that were not run,
665 * and those tasks are drained from the queue
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100666 */
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000667 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;
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100687 try {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000688 queuedTasks = p.shutdownNow();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100689 } catch (SecurityException ok) {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000690 return; // Allowed in case test doesn't have privs
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100691 }
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000692 assertTrue(p.isShutdown());
693 assertTrue(p.getQueue().isEmpty());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000694 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());
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000699 }
700
701 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000702 * shutdownNow returns a list containing tasks that were not run,
703 * and those tasks are drained from the queue
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000704 */
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000705 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;
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000717 try {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000718 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) {
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000728 assertFalse(task.isDone());
729 assertFalse(task.isCancelled());
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000730 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000731 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
732 assertTrue(p.isTerminated());
Przemyslaw Szczepaniaked4f3652016-03-15 09:42:19 +0000733 }
Przemyslaw Szczepaniak5328e072016-03-11 15:59:10 +0000734
735 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000736 * 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 */
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));
Sorin Bascad4c40402021-10-25 08:13:21 +0000786 delayeds.add(p.schedule(task, 1, MILLISECONDS));
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000787
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 /**
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100830 * completed submit of callable returns result
831 */
832 public void testSubmitCallable() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000833 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
834 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100835 Future<String> future = e.submit(new StringTask());
836 String result = future.get();
837 assertSame(TEST_STRING, result);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100838 }
839 }
840
841 /**
842 * completed submit of runnable returns successfully
843 */
844 public void testSubmitRunnable() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000845 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
846 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100847 Future<?> future = e.submit(new NoOpRunnable());
848 future.get();
849 assertTrue(future.isDone());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100850 }
851 }
852
853 /**
854 * completed submit of (runnable, result) returns result
855 */
856 public void testSubmitRunnable2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000857 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
858 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100859 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
860 String result = future.get();
861 assertSame(TEST_STRING, result);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100862 }
863 }
864
865 /**
866 * invokeAny(null) throws NPE
867 */
868 public void testInvokeAny1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000869 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
870 try (PoolCleaner cleaner = cleaner(e)) {
871 try {
872 e.invokeAny(null);
873 shouldThrow();
874 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100875 }
876 }
877
878 /**
879 * invokeAny(empty collection) throws IAE
880 */
881 public void testInvokeAny2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000882 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100888 }
889 }
890
891 /**
892 * invokeAny(c) throws NPE if c has null elements
893 */
894 public void testInvokeAny3() throws Exception {
895 CountDownLatch latch = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000896 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100905 latch.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100906 }
907 }
908
909 /**
910 * invokeAny(c) throws ExecutionException if no task completes
911 */
912 public void testInvokeAny4() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000913 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 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100923 }
924 }
925
926 /**
927 * invokeAny(c) returns result of some task
928 */
929 public void testInvokeAny5() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000930 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
931 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100932 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100937 }
938 }
939
940 /**
941 * invokeAll(null) throws NPE
942 */
943 public void testInvokeAll1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000944 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
945 try (PoolCleaner cleaner = cleaner(e)) {
946 try {
947 e.invokeAll(null);
948 shouldThrow();
949 } catch (NullPointerException success) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100950 }
951 }
952
953 /**
954 * invokeAll(empty collection) returns empty collection
955 */
956 public void testInvokeAll2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000957 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
958 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100959 List<Future<String>> r = e.invokeAll(new ArrayList<Callable<String>>());
960 assertTrue(r.isEmpty());
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100961 }
962 }
963
964 /**
965 * invokeAll(c) throws NPE if c has null elements
966 */
967 public void testInvokeAll3() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000968 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100977 }
978 }
979
980 /**
981 * get of invokeAll(c) throws exception on failed task
982 */
983 public void testInvokeAll4() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000984 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 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100996 }
997 }
998
999 /**
1000 * invokeAll(c) returns results of all completed tasks
1001 */
1002 public void testInvokeAll5() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001003 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
1004 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001005 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());
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001012 }
1013 }
1014
1015 /**
1016 * timed invokeAny(null) throws NPE
1017 */
1018 public void testTimedInvokeAny1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001019 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001025 }
1026 }
1027
1028 /**
1029 * timed invokeAny(,,null) throws NPE
1030 */
1031 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001032 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001040 }
1041 }
1042
1043 /**
1044 * timed invokeAny(empty collection) throws IAE
1045 */
1046 public void testTimedInvokeAny2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001047 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001053 }
1054 }
1055
1056 /**
1057 * timed invokeAny(c) throws NPE if c has null elements
1058 */
1059 public void testTimedInvokeAny3() throws Exception {
1060 CountDownLatch latch = new CountDownLatch(1);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001061 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001070 latch.countDown();
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001071 }
1072 }
1073
1074 /**
1075 * timed invokeAny(c) throws ExecutionException if no task completes
1076 */
1077 public void testTimedInvokeAny4() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001078 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001090 }
1091 }
1092
1093 /**
1094 * timed invokeAny(c) returns result of some task
1095 */
1096 public void testTimedInvokeAny5() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001097 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
1098 try (PoolCleaner cleaner = cleaner(e)) {
1099 long startTime = System.nanoTime();
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001100 List<Callable<String>> l = new ArrayList<Callable<String>>();
1101 l.add(new StringTask());
1102 l.add(new StringTask());
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001103 String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001104 assertSame(TEST_STRING, result);
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001105 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001106 }
1107 }
1108
1109 /**
1110 * timed invokeAll(null) throws NPE
1111 */
1112 public void testTimedInvokeAll1() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001113 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001119 }
1120 }
1121
1122 /**
1123 * timed invokeAll(,,null) throws NPE
1124 */
1125 public void testTimedInvokeAllNullTimeUnit() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001126 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001134 }
1135 }
1136
1137 /**
1138 * timed invokeAll(empty collection) returns empty collection
1139 */
1140 public void testTimedInvokeAll2() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001141 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001145 assertTrue(r.isEmpty());
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001146 }
1147 }
1148
1149 /**
1150 * timed invokeAll(c) throws NPE if c has null elements
1151 */
1152 public void testTimedInvokeAll3() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001153 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) {}
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001162 }
1163 }
1164
1165 /**
1166 * get of element of invokeAll(c) throws exception on failed task
1167 */
1168 public void testTimedInvokeAll4() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001169 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 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001182 }
1183 }
1184
1185 /**
1186 * timed invokeAll(c) returns results of all completed tasks
1187 */
1188 public void testTimedInvokeAll5() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001189 final ExecutorService e = new ScheduledThreadPoolExecutor(2);
1190 try (PoolCleaner cleaner = cleaner(e)) {
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001191 List<Callable<String>> l = new ArrayList<Callable<String>>();
1192 l.add(new StringTask());
1193 l.add(new StringTask());
1194 List<Future<String>> futures =
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001195 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001196 assertEquals(2, futures.size());
1197 for (Future<String> future : futures)
1198 assertSame(TEST_STRING, future.get());
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001199 }
1200 }
1201
1202 /**
1203 * timed invokeAll(c) cancels tasks not completed by timeout
1204 */
1205 public void testTimedInvokeAll6() throws Exception {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +00001206 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);
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001260 }
1261 }
1262
1263}