ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
Revision: 1.71
Committed: Sat Nov 24 21:41:21 2018 UTC (5 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.70: +1 -1 lines
Log Message:
delete SmallPossiblyInterruptedRunnable

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.15 Callable task = new CheckedCallable<Boolean>() {
127     public Boolean realCall() {
128     done.countDown();
129 jsr166 1.26 assertTrue(millisElapsedSince(startTime) >= timeoutMillis());
130 jsr166 1.15 return Boolean.TRUE;
131     }};
132 jsr166 1.26 Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
133     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 jsr166 1.26 Future f = p.schedule(task, timeoutMillis(), MILLISECONDS);
152     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     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     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 jsr166 1.61 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     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 jsr166 1.15 ScheduledFuture[] tasks = new ScheduledFuture[5];
595     for (int i = 0; i < tasks.length; i++) {
596     Runnable r = new CheckedRunnable() {
597     public void realRun() throws InterruptedException {
598     threadStarted.countDown();
599 jsr166 1.52 await(done);
600 jsr166 1.15 }};
601     tasks[i] = p.schedule(r, 1, MILLISECONDS);
602     }
603 jsr166 1.54 await(threadStarted);
604 jsr166 1.15 BlockingQueue<Runnable> q = p.getQueue();
605     assertTrue(q.contains(tasks[tasks.length - 1]));
606 dl 1.1 assertFalse(q.contains(tasks[0]));
607     }
608     }
609    
610     /**
611     * remove(task) removes queued task, and fails to remove active task
612     */
613 jsr166 1.6 public void testRemove() throws InterruptedException {
614 jsr166 1.55 final CountDownLatch done = new CountDownLatch(1);
615 jsr166 1.15 final ScheduledThreadPoolExecutor p = new CustomExecutor(1);
616 jsr166 1.55 try (PoolCleaner cleaner = cleaner(p, done)) {
617 jsr166 1.46 ScheduledFuture[] tasks = new ScheduledFuture[5];
618     final CountDownLatch threadStarted = new CountDownLatch(1);
619 jsr166 1.15 for (int i = 0; i < tasks.length; i++) {
620     Runnable r = new CheckedRunnable() {
621     public void realRun() throws InterruptedException {
622     threadStarted.countDown();
623 jsr166 1.52 await(done);
624 jsr166 1.15 }};
625     tasks[i] = p.schedule(r, 1, MILLISECONDS);
626     }
627 jsr166 1.54 await(threadStarted);
628 jsr166 1.15 BlockingQueue<Runnable> q = p.getQueue();
629     assertFalse(p.remove((Runnable)tasks[0]));
630 dl 1.1 assertTrue(q.contains((Runnable)tasks[4]));
631     assertTrue(q.contains((Runnable)tasks[3]));
632 jsr166 1.15 assertTrue(p.remove((Runnable)tasks[4]));
633     assertFalse(p.remove((Runnable)tasks[4]));
634 dl 1.1 assertFalse(q.contains((Runnable)tasks[4]));
635     assertTrue(q.contains((Runnable)tasks[3]));
636 jsr166 1.15 assertTrue(p.remove((Runnable)tasks[3]));
637 dl 1.1 assertFalse(q.contains((Runnable)tasks[3]));
638     }
639     }
640    
641     /**
642 jsr166 1.14 * purge removes cancelled tasks from the queue
643 dl 1.1 */
644 jsr166 1.6 public void testPurge() throws InterruptedException {
645 jsr166 1.49 final ScheduledFuture[] tasks = new ScheduledFuture[5];
646     final Runnable releaser = new Runnable() { public void run() {
647     for (ScheduledFuture task : tasks)
648     if (task != null) task.cancel(true); }};
649 jsr166 1.46 final CustomExecutor p = new CustomExecutor(1);
650 jsr166 1.49 try (PoolCleaner cleaner = cleaner(p, releaser)) {
651     for (int i = 0; i < tasks.length; i++)
652 jsr166 1.71 tasks[i] = p.schedule(possiblyInterruptedRunnable(SMALL_DELAY_MS),
653 jsr166 1.49 LONG_DELAY_MS, MILLISECONDS);
654 jsr166 1.15 int max = tasks.length;
655 dl 1.1 if (tasks[4].cancel(true)) --max;
656     if (tasks[3].cancel(true)) --max;
657     // There must eventually be an interference-free point at
658     // which purge will not fail. (At worst, when queue is empty.)
659 jsr166 1.22 long startTime = System.nanoTime();
660     do {
661 jsr166 1.15 p.purge();
662     long count = p.getTaskCount();
663 jsr166 1.22 if (count == max)
664     return;
665 jsr166 1.49 } while (millisElapsedSince(startTime) < LONG_DELAY_MS);
666 jsr166 1.22 fail("Purge failed to remove cancelled tasks");
667 dl 1.1 }
668     }
669    
670     /**
671 jsr166 1.37 * shutdownNow returns a list containing tasks that were not run,
672     * and those tasks are drained from the queue
673 dl 1.1 */
674 jsr166 1.40 public void testShutdownNow() throws InterruptedException {
675     final int poolSize = 2;
676     final int count = 5;
677     final AtomicInteger ran = new AtomicInteger(0);
678     final CustomExecutor p = new CustomExecutor(poolSize);
679 jsr166 1.47 final CountDownLatch threadsStarted = new CountDownLatch(poolSize);
680 jsr166 1.42 Runnable waiter = new CheckedRunnable() { public void realRun() {
681 jsr166 1.40 threadsStarted.countDown();
682     try {
683     MILLISECONDS.sleep(2 * LONG_DELAY_MS);
684     } catch (InterruptedException success) {}
685     ran.getAndIncrement();
686     }};
687     for (int i = 0; i < count; i++)
688     p.execute(waiter);
689 jsr166 1.53 await(threadsStarted);
690 jsr166 1.41 assertEquals(poolSize, p.getActiveCount());
691     assertEquals(0, p.getCompletedTaskCount());
692 jsr166 1.40 final List<Runnable> queuedTasks;
693     try {
694     queuedTasks = p.shutdownNow();
695     } catch (SecurityException ok) {
696     return; // Allowed in case test doesn't have privs
697     }
698     assertTrue(p.isShutdown());
699     assertTrue(p.getQueue().isEmpty());
700     assertEquals(count - poolSize, queuedTasks.size());
701     assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
702     assertTrue(p.isTerminated());
703     assertEquals(poolSize, ran.get());
704 jsr166 1.41 assertEquals(poolSize, p.getCompletedTaskCount());
705 jsr166 1.40 }
706    
707     /**
708     * shutdownNow returns a list containing tasks that were not run,
709     * and those tasks are drained from the queue
710     */
711 jsr166 1.38 public void testShutdownNow_delayedTasks() throws InterruptedException {
712 jsr166 1.46 final CustomExecutor p = new CustomExecutor(1);
713 jsr166 1.38 List<ScheduledFuture> tasks = new ArrayList<>();
714     for (int i = 0; i < 3; i++) {
715     Runnable r = new NoOpRunnable();
716     tasks.add(p.schedule(r, 9, SECONDS));
717     tasks.add(p.scheduleAtFixedRate(r, 9, 9, SECONDS));
718     tasks.add(p.scheduleWithFixedDelay(r, 9, 9, SECONDS));
719     }
720 jsr166 1.39 if (testImplementationDetails)
721     assertEquals(new HashSet(tasks), new HashSet(p.getQueue()));
722 jsr166 1.38 final List<Runnable> queuedTasks;
723 dl 1.1 try {
724 jsr166 1.38 queuedTasks = p.shutdownNow();
725 jsr166 1.2 } catch (SecurityException ok) {
726 jsr166 1.38 return; // Allowed in case test doesn't have privs
727     }
728     assertTrue(p.isShutdown());
729     assertTrue(p.getQueue().isEmpty());
730 jsr166 1.39 if (testImplementationDetails)
731     assertEquals(new HashSet(tasks), new HashSet(queuedTasks));
732 jsr166 1.38 assertEquals(tasks.size(), queuedTasks.size());
733     for (ScheduledFuture task : tasks) {
734     assertFalse(((CustomTask)task).ran);
735     assertFalse(task.isDone());
736     assertFalse(task.isCancelled());
737 dl 1.1 }
738 jsr166 1.38 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
739     assertTrue(p.isTerminated());
740 dl 1.1 }
741    
742     /**
743 jsr166 1.42 * By default, periodic tasks are cancelled at shutdown.
744     * By default, delayed tasks keep running after shutdown.
745     * Check that changing the default values work:
746     * - setExecuteExistingDelayedTasksAfterShutdownPolicy
747     * - setContinueExistingPeriodicTasksAfterShutdownPolicy
748     */
749 jsr166 1.69 @SuppressWarnings("FutureReturnValueIgnored")
750 jsr166 1.42 public void testShutdown_cancellation() throws Exception {
751 jsr166 1.66 final int poolSize = 4;
752 jsr166 1.42 final CustomExecutor p = new CustomExecutor(poolSize);
753 jsr166 1.66 final BlockingQueue<Runnable> q = p.getQueue();
754     final ThreadLocalRandom rnd = ThreadLocalRandom.current();
755     final long delay = rnd.nextInt(2);
756     final int rounds = rnd.nextInt(1, 3);
757     final boolean effectiveDelayedPolicy;
758     final boolean effectivePeriodicPolicy;
759     final boolean effectiveRemovePolicy;
760    
761     if (rnd.nextBoolean())
762     p.setExecuteExistingDelayedTasksAfterShutdownPolicy(
763     effectiveDelayedPolicy = rnd.nextBoolean());
764     else
765     effectiveDelayedPolicy = true;
766 jsr166 1.42 assertEquals(effectiveDelayedPolicy,
767     p.getExecuteExistingDelayedTasksAfterShutdownPolicy());
768 jsr166 1.66
769     if (rnd.nextBoolean())
770     p.setContinueExistingPeriodicTasksAfterShutdownPolicy(
771     effectivePeriodicPolicy = rnd.nextBoolean());
772     else
773     effectivePeriodicPolicy = false;
774 jsr166 1.42 assertEquals(effectivePeriodicPolicy,
775     p.getContinueExistingPeriodicTasksAfterShutdownPolicy());
776 jsr166 1.66
777     if (rnd.nextBoolean())
778     p.setRemoveOnCancelPolicy(
779     effectiveRemovePolicy = rnd.nextBoolean());
780     else
781     effectiveRemovePolicy = false;
782 jsr166 1.42 assertEquals(effectiveRemovePolicy,
783     p.getRemoveOnCancelPolicy());
784 jsr166 1.66
785     final boolean periodicTasksContinue = effectivePeriodicPolicy && rnd.nextBoolean();
786    
787     // Strategy: Wedge the pool with one wave of "blocker" tasks,
788     // then add a second wave that waits in the queue until unblocked.
789 jsr166 1.42 final AtomicInteger ran = new AtomicInteger(0);
790     final CountDownLatch poolBlocked = new CountDownLatch(poolSize);
791     final CountDownLatch unblock = new CountDownLatch(1);
792 jsr166 1.66 final RuntimeException exception = new RuntimeException();
793    
794     class Task implements Runnable {
795     public void run() {
796     try {
797     ran.getAndIncrement();
798     poolBlocked.countDown();
799     await(unblock);
800     } catch (Throwable fail) { threadUnexpectedException(fail); }
801     }
802     }
803    
804     class PeriodicTask extends Task {
805     PeriodicTask(int rounds) { this.rounds = rounds; }
806     int rounds;
807     public void run() {
808     if (--rounds == 0) super.run();
809     // throw exception to surely terminate this periodic task,
810     // but in a separate execution and in a detectable way.
811     if (rounds == -1) throw exception;
812     }
813     }
814    
815     Runnable task = new Task();
816    
817     List<Future<?>> immediates = new ArrayList<>();
818     List<Future<?>> delayeds = new ArrayList<>();
819     List<Future<?>> periodics = new ArrayList<>();
820    
821     immediates.add(p.submit(task));
822     delayeds.add(p.schedule(task, delay, MILLISECONDS));
823     periodics.add(p.scheduleAtFixedRate(
824     new PeriodicTask(rounds), delay, 1, MILLISECONDS));
825     periodics.add(p.scheduleWithFixedDelay(
826     new PeriodicTask(rounds), delay, 1, MILLISECONDS));
827    
828 jsr166 1.65 await(poolBlocked);
829 jsr166 1.42
830 jsr166 1.66 assertEquals(poolSize, ran.get());
831     assertEquals(poolSize, p.getActiveCount());
832     assertTrue(q.isEmpty());
833    
834     // Add second wave of tasks.
835     immediates.add(p.submit(task));
836     delayeds.add(p.schedule(task, effectiveDelayedPolicy ? delay : LONG_DELAY_MS, MILLISECONDS));
837     periodics.add(p.scheduleAtFixedRate(
838     new PeriodicTask(rounds), delay, 1, MILLISECONDS));
839     periodics.add(p.scheduleWithFixedDelay(
840     new PeriodicTask(rounds), delay, 1, MILLISECONDS));
841    
842     assertEquals(poolSize, q.size());
843     assertEquals(poolSize, ran.get());
844    
845     immediates.forEach(
846     f -> assertTrue(((ScheduledFuture)f).getDelay(NANOSECONDS) <= 0L));
847    
848 jsr166 1.70 Stream.of(immediates, delayeds, periodics).flatMap(Collection::stream)
849 jsr166 1.66 .forEach(f -> assertFalse(f.isDone()));
850 jsr166 1.2
851 jsr166 1.15 try { p.shutdown(); } catch (SecurityException ok) { return; }
852 jsr166 1.42 assertTrue(p.isShutdown());
853 jsr166 1.66 assertTrue(p.isTerminating());
854 jsr166 1.42 assertFalse(p.isTerminated());
855 jsr166 1.66
856     if (rnd.nextBoolean())
857     assertThrows(
858     RejectedExecutionException.class,
859     () -> p.submit(task),
860     () -> p.schedule(task, 1, SECONDS),
861     () -> p.scheduleAtFixedRate(
862     new PeriodicTask(1), 1, 1, SECONDS),
863     () -> p.scheduleWithFixedDelay(
864     new PeriodicTask(2), 1, 1, SECONDS));
865    
866     assertTrue(q.contains(immediates.get(1)));
867     assertTrue(!effectiveDelayedPolicy
868     ^ q.contains(delayeds.get(1)));
869     assertTrue(!effectivePeriodicPolicy
870     ^ q.containsAll(periodics.subList(2, 4)));
871    
872     immediates.forEach(f -> assertFalse(f.isDone()));
873    
874     assertFalse(delayeds.get(0).isDone());
875     if (effectiveDelayedPolicy)
876     assertFalse(delayeds.get(1).isDone());
877     else
878     assertTrue(delayeds.get(1).isCancelled());
879    
880     if (effectivePeriodicPolicy)
881     periodics.forEach(
882     f -> {
883     assertFalse(f.isDone());
884     if (!periodicTasksContinue) {
885     assertTrue(f.cancel(false));
886     assertTrue(f.isCancelled());
887     }
888     });
889     else {
890     periodics.subList(0, 2).forEach(f -> assertFalse(f.isDone()));
891     periodics.subList(2, 4).forEach(f -> assertTrue(f.isCancelled()));
892 dl 1.1 }
893 jsr166 1.66
894     unblock.countDown(); // Release all pool threads
895    
896 jsr166 1.42 assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
897 jsr166 1.66 assertFalse(p.isTerminating());
898 jsr166 1.15 assertTrue(p.isTerminated());
899 jsr166 1.66
900     assertTrue(q.isEmpty());
901    
902 jsr166 1.70 Stream.of(immediates, delayeds, periodics).flatMap(Collection::stream)
903 jsr166 1.66 .forEach(f -> assertTrue(f.isDone()));
904    
905     for (Future<?> f : immediates) assertNull(f.get());
906    
907     assertNull(delayeds.get(0).get());
908     if (effectiveDelayedPolicy)
909     assertNull(delayeds.get(1).get());
910     else
911     assertTrue(delayeds.get(1).isCancelled());
912    
913     if (periodicTasksContinue)
914     periodics.forEach(
915     f -> {
916     try { f.get(); }
917     catch (ExecutionException success) {
918     assertSame(exception, success.getCause());
919     }
920     catch (Throwable fail) { threadUnexpectedException(fail); }
921     });
922     else
923     periodics.forEach(f -> assertTrue(f.isCancelled()));
924    
925     assertEquals(poolSize + 1
926     + (effectiveDelayedPolicy ? 1 : 0)
927     + (periodicTasksContinue ? 2 : 0),
928     ran.get());
929     }
930 dl 1.1
931     /**
932     * completed submit of callable returns result
933     */
934 jsr166 1.6 public void testSubmitCallable() throws Exception {
935 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
936     try (PoolCleaner cleaner = cleaner(e)) {
937 dl 1.1 Future<String> future = e.submit(new StringTask());
938     String result = future.get();
939     assertSame(TEST_STRING, result);
940     }
941     }
942    
943     /**
944     * completed submit of runnable returns successfully
945     */
946 jsr166 1.6 public void testSubmitRunnable() throws Exception {
947 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
948     try (PoolCleaner cleaner = cleaner(e)) {
949 dl 1.1 Future<?> future = e.submit(new NoOpRunnable());
950     future.get();
951     assertTrue(future.isDone());
952     }
953     }
954    
955     /**
956     * completed submit of (runnable, result) returns result
957     */
958 jsr166 1.6 public void testSubmitRunnable2() throws Exception {
959 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
960     try (PoolCleaner cleaner = cleaner(e)) {
961 dl 1.1 Future<String> future = e.submit(new NoOpRunnable(), TEST_STRING);
962     String result = future.get();
963     assertSame(TEST_STRING, result);
964     }
965     }
966    
967     /**
968     * invokeAny(null) throws NPE
969     */
970 jsr166 1.6 public void testInvokeAny1() throws Exception {
971 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
972     try (PoolCleaner cleaner = cleaner(e)) {
973     try {
974     e.invokeAny(null);
975     shouldThrow();
976     } catch (NullPointerException success) {}
977 dl 1.1 }
978     }
979    
980     /**
981 jsr166 1.68 * invokeAny(empty collection) throws IllegalArgumentException
982 dl 1.1 */
983 jsr166 1.6 public void testInvokeAny2() throws Exception {
984 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
985     try (PoolCleaner cleaner = cleaner(e)) {
986     try {
987     e.invokeAny(new ArrayList<Callable<String>>());
988     shouldThrow();
989     } catch (IllegalArgumentException success) {}
990 dl 1.1 }
991     }
992    
993     /**
994     * invokeAny(c) throws NPE if c has null elements
995     */
996 jsr166 1.6 public void testInvokeAny3() throws Exception {
997 jsr166 1.46 final CountDownLatch latch = new CountDownLatch(1);
998     final ExecutorService e = new CustomExecutor(2);
999     try (PoolCleaner cleaner = cleaner(e)) {
1000 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1001 jsr166 1.46 l.add(latchAwaitingStringTask(latch));
1002     l.add(null);
1003     try {
1004     e.invokeAny(l);
1005     shouldThrow();
1006     } catch (NullPointerException success) {}
1007 jsr166 1.6 latch.countDown();
1008 dl 1.1 }
1009     }
1010    
1011     /**
1012     * invokeAny(c) throws ExecutionException if no task completes
1013     */
1014 jsr166 1.6 public void testInvokeAny4() throws Exception {
1015 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1016     try (PoolCleaner cleaner = cleaner(e)) {
1017 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1018 jsr166 1.46 l.add(new NPETask());
1019     try {
1020     e.invokeAny(l);
1021     shouldThrow();
1022     } catch (ExecutionException success) {
1023     assertTrue(success.getCause() instanceof NullPointerException);
1024     }
1025 dl 1.1 }
1026     }
1027    
1028     /**
1029     * invokeAny(c) returns result of some task
1030     */
1031 jsr166 1.6 public void testInvokeAny5() throws Exception {
1032 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1033     try (PoolCleaner cleaner = cleaner(e)) {
1034 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1035 dl 1.1 l.add(new StringTask());
1036     l.add(new StringTask());
1037     String result = e.invokeAny(l);
1038     assertSame(TEST_STRING, result);
1039     }
1040     }
1041    
1042     /**
1043     * invokeAll(null) throws NPE
1044     */
1045 jsr166 1.6 public void testInvokeAll1() throws Exception {
1046 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1047     try (PoolCleaner cleaner = cleaner(e)) {
1048     try {
1049     e.invokeAll(null);
1050     shouldThrow();
1051     } catch (NullPointerException success) {}
1052 dl 1.1 }
1053     }
1054    
1055     /**
1056 jsr166 1.68 * invokeAll(empty collection) returns empty list
1057 dl 1.1 */
1058 jsr166 1.6 public void testInvokeAll2() throws Exception {
1059 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1060 jsr166 1.68 final Collection<Callable<String>> emptyCollection
1061     = Collections.emptyList();
1062 jsr166 1.46 try (PoolCleaner cleaner = cleaner(e)) {
1063 jsr166 1.68 List<Future<String>> r = e.invokeAll(emptyCollection);
1064 dl 1.1 assertTrue(r.isEmpty());
1065     }
1066     }
1067    
1068     /**
1069     * invokeAll(c) throws NPE if c has null elements
1070     */
1071 jsr166 1.6 public void testInvokeAll3() throws Exception {
1072 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1073     try (PoolCleaner cleaner = cleaner(e)) {
1074 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1075 jsr166 1.46 l.add(new StringTask());
1076     l.add(null);
1077     try {
1078     e.invokeAll(l);
1079     shouldThrow();
1080     } catch (NullPointerException success) {}
1081 dl 1.1 }
1082     }
1083    
1084     /**
1085     * get of invokeAll(c) throws exception on failed task
1086     */
1087 jsr166 1.6 public void testInvokeAll4() throws Exception {
1088 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1089     try (PoolCleaner cleaner = cleaner(e)) {
1090 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1091 jsr166 1.46 l.add(new NPETask());
1092     List<Future<String>> futures = e.invokeAll(l);
1093     assertEquals(1, futures.size());
1094     try {
1095     futures.get(0).get();
1096     shouldThrow();
1097     } catch (ExecutionException success) {
1098     assertTrue(success.getCause() instanceof NullPointerException);
1099     }
1100 dl 1.1 }
1101     }
1102    
1103     /**
1104     * invokeAll(c) returns results of all completed tasks
1105     */
1106 jsr166 1.6 public void testInvokeAll5() throws Exception {
1107 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1108     try (PoolCleaner cleaner = cleaner(e)) {
1109 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1110 dl 1.1 l.add(new StringTask());
1111     l.add(new StringTask());
1112 jsr166 1.11 List<Future<String>> futures = e.invokeAll(l);
1113     assertEquals(2, futures.size());
1114     for (Future<String> future : futures)
1115 jsr166 1.6 assertSame(TEST_STRING, future.get());
1116 dl 1.1 }
1117     }
1118    
1119     /**
1120     * timed invokeAny(null) throws NPE
1121     */
1122 jsr166 1.6 public void testTimedInvokeAny1() throws Exception {
1123 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1124     try (PoolCleaner cleaner = cleaner(e)) {
1125     try {
1126 jsr166 1.68 e.invokeAny(null, randomTimeout(), randomTimeUnit());
1127 jsr166 1.46 shouldThrow();
1128     } catch (NullPointerException success) {}
1129 dl 1.1 }
1130     }
1131    
1132     /**
1133     * timed invokeAny(,,null) throws NPE
1134     */
1135 jsr166 1.6 public void testTimedInvokeAnyNullTimeUnit() throws Exception {
1136 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1137     try (PoolCleaner cleaner = cleaner(e)) {
1138 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1139 jsr166 1.46 l.add(new StringTask());
1140     try {
1141 jsr166 1.68 e.invokeAny(l, randomTimeout(), null);
1142 jsr166 1.46 shouldThrow();
1143     } catch (NullPointerException success) {}
1144 dl 1.1 }
1145     }
1146    
1147     /**
1148 jsr166 1.68 * timed invokeAny(empty collection) throws IllegalArgumentException
1149 dl 1.1 */
1150 jsr166 1.6 public void testTimedInvokeAny2() throws Exception {
1151 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1152 jsr166 1.68 final Collection<Callable<String>> emptyCollection
1153     = Collections.emptyList();
1154 jsr166 1.46 try (PoolCleaner cleaner = cleaner(e)) {
1155     try {
1156 jsr166 1.68 e.invokeAny(emptyCollection, randomTimeout(), randomTimeUnit());
1157 jsr166 1.46 shouldThrow();
1158     } catch (IllegalArgumentException success) {}
1159 dl 1.1 }
1160     }
1161    
1162     /**
1163     * timed invokeAny(c) throws NPE if c has null elements
1164     */
1165 jsr166 1.6 public void testTimedInvokeAny3() throws Exception {
1166 jsr166 1.11 CountDownLatch latch = new CountDownLatch(1);
1167 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1168     try (PoolCleaner cleaner = cleaner(e)) {
1169 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1170 jsr166 1.46 l.add(latchAwaitingStringTask(latch));
1171     l.add(null);
1172     try {
1173 jsr166 1.68 e.invokeAny(l, randomTimeout(), randomTimeUnit());
1174 jsr166 1.46 shouldThrow();
1175     } catch (NullPointerException success) {}
1176 jsr166 1.6 latch.countDown();
1177 dl 1.1 }
1178     }
1179    
1180     /**
1181     * timed invokeAny(c) throws ExecutionException if no task completes
1182     */
1183 jsr166 1.6 public void testTimedInvokeAny4() throws Exception {
1184 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1185     try (PoolCleaner cleaner = cleaner(e)) {
1186 jsr166 1.57 long startTime = System.nanoTime();
1187 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1188 jsr166 1.46 l.add(new NPETask());
1189     try {
1190 jsr166 1.57 e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1191 jsr166 1.46 shouldThrow();
1192     } catch (ExecutionException success) {
1193     assertTrue(success.getCause() instanceof NullPointerException);
1194     }
1195 jsr166 1.57 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1196 dl 1.1 }
1197     }
1198    
1199     /**
1200     * timed invokeAny(c) returns result of some task
1201     */
1202 jsr166 1.6 public void testTimedInvokeAny5() throws Exception {
1203 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1204     try (PoolCleaner cleaner = cleaner(e)) {
1205 jsr166 1.58 long startTime = System.nanoTime();
1206 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1207 dl 1.1 l.add(new StringTask());
1208     l.add(new StringTask());
1209 jsr166 1.58 String result = e.invokeAny(l, LONG_DELAY_MS, MILLISECONDS);
1210 dl 1.1 assertSame(TEST_STRING, result);
1211 jsr166 1.58 assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1212 dl 1.1 }
1213     }
1214    
1215     /**
1216 jsr166 1.68 * timed invokeAll(null) throws NullPointerException
1217 dl 1.1 */
1218 jsr166 1.6 public void testTimedInvokeAll1() throws Exception {
1219 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1220     try (PoolCleaner cleaner = cleaner(e)) {
1221     try {
1222 jsr166 1.68 e.invokeAll(null, randomTimeout(), randomTimeUnit());
1223 jsr166 1.46 shouldThrow();
1224     } catch (NullPointerException success) {}
1225 dl 1.1 }
1226     }
1227    
1228     /**
1229 jsr166 1.68 * timed invokeAll(,,null) throws NullPointerException
1230 dl 1.1 */
1231 jsr166 1.6 public void testTimedInvokeAllNullTimeUnit() throws Exception {
1232 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1233     try (PoolCleaner cleaner = cleaner(e)) {
1234 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1235 jsr166 1.46 l.add(new StringTask());
1236     try {
1237 jsr166 1.68 e.invokeAll(l, randomTimeout(), null);
1238 jsr166 1.46 shouldThrow();
1239     } catch (NullPointerException success) {}
1240 dl 1.1 }
1241     }
1242    
1243     /**
1244 jsr166 1.68 * timed invokeAll(empty collection) returns empty list
1245 dl 1.1 */
1246 jsr166 1.6 public void testTimedInvokeAll2() throws Exception {
1247 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1248 jsr166 1.68 final Collection<Callable<String>> emptyCollection
1249     = Collections.emptyList();
1250 jsr166 1.46 try (PoolCleaner cleaner = cleaner(e)) {
1251 jsr166 1.68 List<Future<String>> r =
1252     e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit());
1253 dl 1.1 assertTrue(r.isEmpty());
1254     }
1255     }
1256    
1257     /**
1258     * timed invokeAll(c) throws NPE if c has null elements
1259     */
1260 jsr166 1.6 public void testTimedInvokeAll3() throws Exception {
1261 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1262     try (PoolCleaner cleaner = cleaner(e)) {
1263 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1264 jsr166 1.46 l.add(new StringTask());
1265     l.add(null);
1266     try {
1267 jsr166 1.68 e.invokeAll(l, randomTimeout(), randomTimeUnit());
1268 jsr166 1.46 shouldThrow();
1269     } catch (NullPointerException success) {}
1270 dl 1.1 }
1271     }
1272    
1273     /**
1274     * get of element of invokeAll(c) throws exception on failed task
1275     */
1276 jsr166 1.6 public void testTimedInvokeAll4() throws Exception {
1277 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1278 jsr166 1.68 final Collection<Callable<String>> c = new ArrayList<>();
1279     c.add(new NPETask());
1280 jsr166 1.46 try (PoolCleaner cleaner = cleaner(e)) {
1281     List<Future<String>> futures =
1282 jsr166 1.68 e.invokeAll(c, LONG_DELAY_MS, MILLISECONDS);
1283 jsr166 1.46 assertEquals(1, futures.size());
1284     try {
1285     futures.get(0).get();
1286     shouldThrow();
1287     } catch (ExecutionException success) {
1288     assertTrue(success.getCause() instanceof NullPointerException);
1289     }
1290 dl 1.1 }
1291     }
1292    
1293     /**
1294     * timed invokeAll(c) returns results of all completed tasks
1295     */
1296 jsr166 1.6 public void testTimedInvokeAll5() throws Exception {
1297 jsr166 1.46 final ExecutorService e = new CustomExecutor(2);
1298     try (PoolCleaner cleaner = cleaner(e)) {
1299 jsr166 1.64 List<Callable<String>> l = new ArrayList<>();
1300 dl 1.1 l.add(new StringTask());
1301     l.add(new StringTask());
1302 jsr166 1.11 List<Future<String>> futures =
1303 jsr166 1.43 e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1304 jsr166 1.11 assertEquals(2, futures.size());
1305     for (Future<String> future : futures)
1306 jsr166 1.6 assertSame(TEST_STRING, future.get());
1307 dl 1.1 }
1308     }
1309    
1310     /**
1311     * timed invokeAll(c) cancels tasks not completed by timeout
1312     */
1313 jsr166 1.6 public void testTimedInvokeAll6() throws Exception {
1314 jsr166 1.56 for (long timeout = timeoutMillis();;) {
1315     final CountDownLatch done = new CountDownLatch(1);
1316     final Callable<String> waiter = new CheckedCallable<String>() {
1317     public String realCall() {
1318     try { done.await(LONG_DELAY_MS, MILLISECONDS); }
1319     catch (InterruptedException ok) {}
1320     return "1"; }};
1321     final ExecutorService p = new CustomExecutor(2);
1322     try (PoolCleaner cleaner = cleaner(p, done)) {
1323 jsr166 1.36 List<Callable<String>> tasks = new ArrayList<>();
1324     tasks.add(new StringTask("0"));
1325 jsr166 1.56 tasks.add(waiter);
1326 jsr166 1.36 tasks.add(new StringTask("2"));
1327     long startTime = System.nanoTime();
1328     List<Future<String>> futures =
1329 jsr166 1.56 p.invokeAll(tasks, timeout, MILLISECONDS);
1330 jsr166 1.36 assertEquals(tasks.size(), futures.size());
1331     assertTrue(millisElapsedSince(startTime) >= timeout);
1332     for (Future future : futures)
1333     assertTrue(future.isDone());
1334     assertTrue(futures.get(1).isCancelled());
1335     try {
1336     assertEquals("0", futures.get(0).get());
1337     assertEquals("2", futures.get(2).get());
1338     break;
1339     } catch (CancellationException retryWithLongerTimeout) {
1340     timeout *= 2;
1341     if (timeout >= LONG_DELAY_MS / 2)
1342     fail("expected exactly one task to be cancelled");
1343     }
1344     }
1345 dl 1.1 }
1346     }
1347    
1348     }