ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.47
Committed: Mon Oct 5 20:45:41 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.46: +1 -1 lines
Log Message:
fix minor 4jdk7-tck bitrot

File Contents

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