ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.64
Committed: Wed Jan 4 06:09:58 2017 UTC (7 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.63: +14 -14 lines
Log Message:
convert to Diamond

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