ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.58
Committed: Thu Oct 8 03:08:37 2015 UTC (8 years, 7 months ago) by jsr166
Branch: MAIN
Changes since 1.57: +3 -1 lines
Log Message:
improve testTimedInvokeAny5

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