ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.44
Committed: Sun Oct 4 02:11:44 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.43: +1 -1 lines
Log Message:
avoid using SMALL_DELAY_MS

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