ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.74
Committed: Wed Jan 27 01:57:24 2021 UTC (3 years, 3 months ago) by jsr166
Branch: MAIN
CVS Tags: HEAD
Changes since 1.73: +2 -2 lines
Log Message:
use diamond <> pervasively

File Contents

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