ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/tck/ScheduledExecutorSubclassTest.java
(Generate patch)

Comparing jsr166/src/test/tck/ScheduledExecutorSubclassTest.java (file contents):
Revision 1.5 by jsr166, Fri Nov 20 16:00:19 2009 UTC vs.
Revision 1.31 by jsr166, Tue Sep 24 18:35:21 2013 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines