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

Comparing jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java (file contents):
Revision 1.20 by jsr166, Sat Oct 9 22:27:16 2010 UTC vs.
Revision 1.54 by jsr166, Sun Oct 4 01:27:32 2015 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   * Other contributors include Andrew Wright, Jeffrey Hayes,
6   * Pat Fisher, Mike Judd.
7   */
8  
9 import java.util.concurrent.*;
9   import static java.util.concurrent.TimeUnit.MILLISECONDS;
10 < import java.util.concurrent.locks.*;
10 > import static java.util.concurrent.TimeUnit.SECONDS;
11  
12 < import junit.framework.*;
13 < import java.util.*;
12 > import java.util.ArrayList;
13 > import java.util.List;
14 > import java.util.concurrent.ArrayBlockingQueue;
15 > import java.util.concurrent.BlockingQueue;
16 > import java.util.concurrent.Callable;
17 > import java.util.concurrent.CancellationException;
18 > import java.util.concurrent.CountDownLatch;
19 > import java.util.concurrent.ExecutionException;
20 > import java.util.concurrent.Executors;
21 > import java.util.concurrent.ExecutorService;
22 > import java.util.concurrent.Future;
23 > import java.util.concurrent.FutureTask;
24 > import java.util.concurrent.LinkedBlockingQueue;
25 > import java.util.concurrent.RejectedExecutionException;
26 > import java.util.concurrent.RejectedExecutionHandler;
27 > import java.util.concurrent.RunnableFuture;
28 > import java.util.concurrent.SynchronousQueue;
29 > import java.util.concurrent.ThreadFactory;
30 > import java.util.concurrent.ThreadPoolExecutor;
31 > import java.util.concurrent.TimeoutException;
32 > import java.util.concurrent.TimeUnit;
33 > import java.util.concurrent.atomic.AtomicInteger;
34 > import java.util.concurrent.locks.Condition;
35 > import java.util.concurrent.locks.ReentrantLock;
36 >
37 > import junit.framework.Test;
38 > import junit.framework.TestSuite;
39  
40   public class ThreadPoolExecutorSubclassTest extends JSR166TestCase {
41      public static void main(String[] args) {
42 <        junit.textui.TestRunner.run(suite());
42 >        main(suite(), args);
43      }
44      public static Test suite() {
45          return new TestSuite(ThreadPoolExecutorSubclassTest.class);
# Line 37 | Line 61 | public class ThreadPoolExecutorSubclassT
61          CustomTask(final Runnable r, final V res) {
62              if (r == null) throw new NullPointerException();
63              callable = new Callable<V>() {
64 <            public V call() throws Exception { r.run(); return res; }};
64 >                public V call() throws Exception { r.run(); return res; }};
65          }
66          public boolean isDone() {
67              lock.lock(); try { return done; } finally { lock.unlock() ; }
# Line 60 | Line 84 | public class ThreadPoolExecutorSubclassT
84              finally { lock.unlock() ; }
85          }
86          public void run() {
63            boolean runme;
87              lock.lock();
88              try {
89 <                runme = !done;
90 <                if (!runme)
91 <                    thread = Thread.currentThread();
89 >                if (done)
90 >                    return;
91 >                thread = Thread.currentThread();
92              }
93              finally { lock.unlock() ; }
71            if (!runme) return;
94              V v = null;
95              Exception e = null;
96              try {
# Line 79 | Line 101 | public class ThreadPoolExecutorSubclassT
101              }
102              lock.lock();
103              try {
104 <                result = v;
105 <                exception = e;
106 <                done = true;
107 <                thread = null;
108 <                cond.signalAll();
104 >                if (!done) {
105 >                    result = v;
106 >                    exception = e;
107 >                    done = true;
108 >                    thread = null;
109 >                    cond.signalAll();
110 >                }
111              }
112              finally { lock.unlock(); }
113          }
# Line 92 | Line 116 | public class ThreadPoolExecutorSubclassT
116              try {
117                  while (!done)
118                      cond.await();
119 +                if (cancelled)
120 +                    throw new CancellationException();
121                  if (exception != null)
122                      throw new ExecutionException(exception);
123                  return result;
# Line 103 | Line 129 | public class ThreadPoolExecutorSubclassT
129              long nanos = unit.toNanos(timeout);
130              lock.lock();
131              try {
132 <                for (;;) {
133 <                    if (done) break;
108 <                    if (nanos < 0)
132 >                while (!done) {
133 >                    if (nanos <= 0L)
134                          throw new TimeoutException();
135                      nanos = cond.awaitNanos(nanos);
136                  }
137 +                if (cancelled)
138 +                    throw new CancellationException();
139                  if (exception != null)
140                      throw new ExecutionException(exception);
141                  return result;
# Line 117 | Line 144 | public class ThreadPoolExecutorSubclassT
144          }
145      }
146  
120
147      static class CustomTPE extends ThreadPoolExecutor {
148          protected <V> RunnableFuture<V> newTaskFor(Callable<V> c) {
149              return new CustomTask<V>(c);
# Line 164 | Line 190 | public class ThreadPoolExecutorSubclassT
190                workQueue, threadFactory, handler);
191          }
192  
193 <        volatile boolean beforeCalled = false;
194 <        volatile boolean afterCalled = false;
195 <        volatile boolean terminatedCalled = false;
193 >        final CountDownLatch beforeCalled = new CountDownLatch(1);
194 >        final CountDownLatch afterCalled = new CountDownLatch(1);
195 >        final CountDownLatch terminatedCalled = new CountDownLatch(1);
196 >
197          public CustomTPE() {
198              super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue<Runnable>());
199          }
200          protected void beforeExecute(Thread t, Runnable r) {
201 <            beforeCalled = true;
201 >            beforeCalled.countDown();
202          }
203          protected void afterExecute(Runnable r, Throwable t) {
204 <            afterCalled = true;
204 >            afterCalled.countDown();
205          }
206          protected void terminated() {
207 <            terminatedCalled = true;
207 >            terminatedCalled.countDown();
208          }
209  
210 +        public boolean beforeCalled() {
211 +            return beforeCalled.getCount() == 0;
212 +        }
213 +        public boolean afterCalled() {
214 +            return afterCalled.getCount() == 0;
215 +        }
216 +        public boolean terminatedCalled() {
217 +            return terminatedCalled.getCount() == 0;
218 +        }
219      }
220  
221      static class FailingThreadFactory implements ThreadFactory {
# Line 190 | Line 226 | public class ThreadPoolExecutorSubclassT
226          }
227      }
228  
193
229      /**
230       * execute successfully executes a runnable
231       */
232      public void testExecute() throws InterruptedException {
233 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
234 <        try {
235 <            p1.execute(new ShortRunnable());
236 <            Thread.sleep(SMALL_DELAY_MS);
237 <        } finally {
238 <            joinPool(p1);
233 >        final ThreadPoolExecutor p =
234 >            new CustomTPE(1, 1,
235 >                          2 * LONG_DELAY_MS, MILLISECONDS,
236 >                          new ArrayBlockingQueue<Runnable>(10));
237 >        try (PoolCleaner cleaner = cleaner(p)) {
238 >            final CountDownLatch done = new CountDownLatch(1);
239 >            final Runnable task = new CheckedRunnable() {
240 >                public void realRun() { done.countDown(); }};
241 >            p.execute(task);
242 >            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
243          }
244      }
245  
# Line 209 | Line 248 | public class ThreadPoolExecutorSubclassT
248       * thread becomes active
249       */
250      public void testGetActiveCount() throws InterruptedException {
251 <        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
252 <        assertEquals(0, p2.getActiveCount());
253 <        p2.execute(new MediumRunnable());
254 <        Thread.sleep(SHORT_DELAY_MS);
255 <        assertEquals(1, p2.getActiveCount());
256 <        joinPool(p2);
251 >        final ThreadPoolExecutor p =
252 >            new CustomTPE(2, 2,
253 >                          LONG_DELAY_MS, MILLISECONDS,
254 >                          new ArrayBlockingQueue<Runnable>(10));
255 >        final CountDownLatch threadStarted = new CountDownLatch(1);
256 >        final CountDownLatch done = new CountDownLatch(1);
257 >        try (PoolCleaner cleaner = cleaner(p)) {
258 >            assertEquals(0, p.getActiveCount());
259 >            p.execute(new CheckedRunnable() {
260 >                public void realRun() throws InterruptedException {
261 >                    threadStarted.countDown();
262 >                    assertEquals(1, p.getActiveCount());
263 >                    done.await();
264 >                }});
265 >            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
266 >            assertEquals(1, p.getActiveCount());
267 >            done.countDown();
268 >        }
269      }
270  
271      /**
272       * prestartCoreThread starts a thread if under corePoolSize, else doesn't
273       */
274      public void testPrestartCoreThread() {
275 <        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
276 <        assertEquals(0, p2.getPoolSize());
277 <        assertTrue(p2.prestartCoreThread());
278 <        assertEquals(1, p2.getPoolSize());
279 <        assertTrue(p2.prestartCoreThread());
280 <        assertEquals(2, p2.getPoolSize());
281 <        assertFalse(p2.prestartCoreThread());
282 <        assertEquals(2, p2.getPoolSize());
283 <        joinPool(p2);
275 >        ThreadPoolExecutor p =
276 >            new CustomTPE(2, 6,
277 >                          LONG_DELAY_MS, MILLISECONDS,
278 >                          new ArrayBlockingQueue<Runnable>(10));
279 >        try (PoolCleaner cleaner = cleaner(p)) {
280 >            assertEquals(0, p.getPoolSize());
281 >            assertTrue(p.prestartCoreThread());
282 >            assertEquals(1, p.getPoolSize());
283 >            assertTrue(p.prestartCoreThread());
284 >            assertEquals(2, p.getPoolSize());
285 >            assertFalse(p.prestartCoreThread());
286 >            assertEquals(2, p.getPoolSize());
287 >            p.setCorePoolSize(4);
288 >            assertTrue(p.prestartCoreThread());
289 >            assertEquals(3, p.getPoolSize());
290 >            assertTrue(p.prestartCoreThread());
291 >            assertEquals(4, p.getPoolSize());
292 >            assertFalse(p.prestartCoreThread());
293 >            assertEquals(4, p.getPoolSize());
294 >        }
295      }
296  
297      /**
298       * prestartAllCoreThreads starts all corePoolSize threads
299       */
300      public void testPrestartAllCoreThreads() {
301 <        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
302 <        assertEquals(0, p2.getPoolSize());
303 <        p2.prestartAllCoreThreads();
304 <        assertEquals(2, p2.getPoolSize());
305 <        p2.prestartAllCoreThreads();
306 <        assertEquals(2, p2.getPoolSize());
307 <        joinPool(p2);
301 >        ThreadPoolExecutor p =
302 >            new CustomTPE(2, 6,
303 >                          LONG_DELAY_MS, MILLISECONDS,
304 >                          new ArrayBlockingQueue<Runnable>(10));
305 >        try (PoolCleaner cleaner = cleaner(p)) {
306 >            assertEquals(0, p.getPoolSize());
307 >            p.prestartAllCoreThreads();
308 >            assertEquals(2, p.getPoolSize());
309 >            p.prestartAllCoreThreads();
310 >            assertEquals(2, p.getPoolSize());
311 >            p.setCorePoolSize(4);
312 >            p.prestartAllCoreThreads();
313 >            assertEquals(4, p.getPoolSize());
314 >            p.prestartAllCoreThreads();
315 >            assertEquals(4, p.getPoolSize());
316 >        }
317      }
318  
319      /**
# Line 250 | Line 321 | public class ThreadPoolExecutorSubclassT
321       * when tasks complete
322       */
323      public void testGetCompletedTaskCount() throws InterruptedException {
324 <        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
325 <        assertEquals(0, p2.getCompletedTaskCount());
326 <        p2.execute(new ShortRunnable());
327 <        Thread.sleep(SMALL_DELAY_MS);
328 <        assertEquals(1, p2.getCompletedTaskCount());
329 <        try { p2.shutdown(); } catch (SecurityException ok) { return; }
330 <        joinPool(p2);
324 >        final ThreadPoolExecutor p =
325 >            new CustomTPE(2, 2,
326 >                          LONG_DELAY_MS, MILLISECONDS,
327 >                          new ArrayBlockingQueue<Runnable>(10));
328 >        try (PoolCleaner cleaner = cleaner(p)) {
329 >            final CountDownLatch threadStarted = new CountDownLatch(1);
330 >            final CountDownLatch threadProceed = new CountDownLatch(1);
331 >            final CountDownLatch threadDone = new CountDownLatch(1);
332 >            assertEquals(0, p.getCompletedTaskCount());
333 >            p.execute(new CheckedRunnable() {
334 >                public void realRun() throws InterruptedException {
335 >                    threadStarted.countDown();
336 >                    assertEquals(0, p.getCompletedTaskCount());
337 >                    threadProceed.await();
338 >                    threadDone.countDown();
339 >                }});
340 >            await(threadStarted);
341 >            assertEquals(0, p.getCompletedTaskCount());
342 >            threadProceed.countDown();
343 >            threadDone.await();
344 >            long startTime = System.nanoTime();
345 >            while (p.getCompletedTaskCount() != 1) {
346 >                if (millisElapsedSince(startTime) > LONG_DELAY_MS)
347 >                    fail("timed out");
348 >                Thread.yield();
349 >            }
350 >        }
351      }
352  
353      /**
354       * getCorePoolSize returns size given in constructor if not otherwise set
355       */
356      public void testGetCorePoolSize() {
357 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
358 <        assertEquals(1, p1.getCorePoolSize());
359 <        joinPool(p1);
357 >        ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
358 >        assertEquals(1, p.getCorePoolSize());
359 >        joinPool(p);
360      }
361  
362      /**
363       * getKeepAliveTime returns value given in constructor if not otherwise set
364       */
365      public void testGetKeepAliveTime() {
366 <        ThreadPoolExecutor p2 = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
367 <        assertEquals(1, p2.getKeepAliveTime(TimeUnit.SECONDS));
368 <        joinPool(p2);
366 >        ThreadPoolExecutor p = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
367 >        assertEquals(1, p.getKeepAliveTime(SECONDS));
368 >        joinPool(p);
369      }
370  
280
371      /**
372       * getThreadFactory returns factory in constructor if not set
373       */
# Line 299 | Line 389 | public class ThreadPoolExecutorSubclassT
389          joinPool(p);
390      }
391  
302
392      /**
393       * setThreadFactory(null) throws NPE
394       */
# Line 336 | Line 425 | public class ThreadPoolExecutorSubclassT
425          joinPool(p);
426      }
427  
339
428      /**
429       * setRejectedExecutionHandler(null) throws NPE
430       */
# Line 351 | Line 439 | public class ThreadPoolExecutorSubclassT
439          }
440      }
441  
354
442      /**
443       * getLargestPoolSize increases, but doesn't overestimate, when
444       * multiple threads active
445       */
446      public void testGetLargestPoolSize() throws InterruptedException {
447 <        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
448 <        assertEquals(0, p2.getLargestPoolSize());
449 <        p2.execute(new MediumRunnable());
450 <        p2.execute(new MediumRunnable());
451 <        Thread.sleep(SHORT_DELAY_MS);
452 <        assertEquals(2, p2.getLargestPoolSize());
453 <        joinPool(p2);
447 >        final int THREADS = 3;
448 >        final ThreadPoolExecutor p =
449 >            new CustomTPE(THREADS, THREADS,
450 >                          LONG_DELAY_MS, MILLISECONDS,
451 >                          new ArrayBlockingQueue<Runnable>(10));
452 >        final CountDownLatch threadsStarted = new CountDownLatch(THREADS);
453 >        final CountDownLatch done = new CountDownLatch(1);
454 >        try {
455 >            assertEquals(0, p.getLargestPoolSize());
456 >            for (int i = 0; i < THREADS; i++)
457 >                p.execute(new CheckedRunnable() {
458 >                    public void realRun() throws InterruptedException {
459 >                        threadsStarted.countDown();
460 >                        done.await();
461 >                        assertEquals(THREADS, p.getLargestPoolSize());
462 >                    }});
463 >            assertTrue(threadsStarted.await(SMALL_DELAY_MS, MILLISECONDS));
464 >            assertEquals(THREADS, p.getLargestPoolSize());
465 >        } finally {
466 >            done.countDown();
467 >            joinPool(p);
468 >            assertEquals(THREADS, p.getLargestPoolSize());
469 >        }
470      }
471  
472      /**
# Line 371 | Line 474 | public class ThreadPoolExecutorSubclassT
474       * otherwise set
475       */
476      public void testGetMaximumPoolSize() {
477 <        ThreadPoolExecutor p2 = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
478 <        assertEquals(2, p2.getMaximumPoolSize());
479 <        joinPool(p2);
477 >        ThreadPoolExecutor p = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
478 >        assertEquals(2, p.getMaximumPoolSize());
479 >        joinPool(p);
480      }
481  
482      /**
483       * getPoolSize increases, but doesn't overestimate, when threads
484       * become active
485       */
486 <    public void testGetPoolSize() {
487 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
488 <        assertEquals(0, p1.getPoolSize());
489 <        p1.execute(new MediumRunnable());
490 <        assertEquals(1, p1.getPoolSize());
491 <        joinPool(p1);
486 >    public void testGetPoolSize() throws InterruptedException {
487 >        final ThreadPoolExecutor p =
488 >            new CustomTPE(1, 1,
489 >                          LONG_DELAY_MS, MILLISECONDS,
490 >                          new ArrayBlockingQueue<Runnable>(10));
491 >        final CountDownLatch threadStarted = new CountDownLatch(1);
492 >        final CountDownLatch done = new CountDownLatch(1);
493 >        try {
494 >            assertEquals(0, p.getPoolSize());
495 >            p.execute(new CheckedRunnable() {
496 >                public void realRun() throws InterruptedException {
497 >                    threadStarted.countDown();
498 >                    assertEquals(1, p.getPoolSize());
499 >                    done.await();
500 >                }});
501 >            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
502 >            assertEquals(1, p.getPoolSize());
503 >        } finally {
504 >            done.countDown();
505 >            joinPool(p);
506 >        }
507      }
508  
509      /**
510       * getTaskCount increases, but doesn't overestimate, when tasks submitted
511       */
512      public void testGetTaskCount() throws InterruptedException {
513 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
514 <        assertEquals(0, p1.getTaskCount());
515 <        p1.execute(new MediumRunnable());
516 <        Thread.sleep(SHORT_DELAY_MS);
517 <        assertEquals(1, p1.getTaskCount());
518 <        joinPool(p1);
513 >        final ThreadPoolExecutor p =
514 >            new CustomTPE(1, 1,
515 >                          LONG_DELAY_MS, MILLISECONDS,
516 >                          new ArrayBlockingQueue<Runnable>(10));
517 >        final CountDownLatch threadStarted = new CountDownLatch(1);
518 >        final CountDownLatch done = new CountDownLatch(1);
519 >        try {
520 >            assertEquals(0, p.getTaskCount());
521 >            p.execute(new CheckedRunnable() {
522 >                public void realRun() throws InterruptedException {
523 >                    threadStarted.countDown();
524 >                    assertEquals(1, p.getTaskCount());
525 >                    done.await();
526 >                }});
527 >            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
528 >            assertEquals(1, p.getTaskCount());
529 >        } finally {
530 >            done.countDown();
531 >            joinPool(p);
532 >        }
533      }
534  
535      /**
536 <     * isShutDown is false before shutdown, true after
536 >     * isShutdown is false before shutdown, true after
537       */
538      public void testIsShutdown() {
539  
540 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
541 <        assertFalse(p1.isShutdown());
542 <        try { p1.shutdown(); } catch (SecurityException ok) { return; }
543 <        assertTrue(p1.isShutdown());
544 <        joinPool(p1);
540 >        ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
541 >        assertFalse(p.isShutdown());
542 >        try { p.shutdown(); } catch (SecurityException ok) { return; }
543 >        assertTrue(p.isShutdown());
544 >        joinPool(p);
545      }
546  
415
547      /**
548       * isTerminated is false before termination, true after
549       */
550      public void testIsTerminated() throws InterruptedException {
551 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
552 <        assertFalse(p1.isTerminated());
553 <        try {
554 <            p1.execute(new MediumRunnable());
555 <        } finally {
556 <            try { p1.shutdown(); } catch (SecurityException ok) { return; }
557 <        }
558 <        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
559 <        assertTrue(p1.isTerminated());
551 >        final ThreadPoolExecutor p =
552 >            new CustomTPE(1, 1,
553 >                          LONG_DELAY_MS, MILLISECONDS,
554 >                          new ArrayBlockingQueue<Runnable>(10));
555 >        final CountDownLatch threadStarted = new CountDownLatch(1);
556 >        final CountDownLatch done = new CountDownLatch(1);
557 >        try {
558 >            assertFalse(p.isTerminating());
559 >            p.execute(new CheckedRunnable() {
560 >                public void realRun() throws InterruptedException {
561 >                    assertFalse(p.isTerminating());
562 >                    threadStarted.countDown();
563 >                    done.await();
564 >                }});
565 >            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
566 >            assertFalse(p.isTerminating());
567 >            done.countDown();
568 >        } finally {
569 >            try { p.shutdown(); } catch (SecurityException ok) { return; }
570 >        }
571 >        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
572 >        assertTrue(p.isTerminated());
573 >        assertFalse(p.isTerminating());
574      }
575  
576      /**
577       * isTerminating is not true when running or when terminated
578       */
579      public void testIsTerminating() throws InterruptedException {
580 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
581 <        assertFalse(p1.isTerminating());
582 <        try {
583 <            p1.execute(new SmallRunnable());
584 <            assertFalse(p1.isTerminating());
585 <        } finally {
586 <            try { p1.shutdown(); } catch (SecurityException ok) { return; }
587 <        }
588 <        assertTrue(p1.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
589 <        assertTrue(p1.isTerminated());
590 <        assertFalse(p1.isTerminating());
580 >        final ThreadPoolExecutor p =
581 >            new CustomTPE(1, 1,
582 >                          LONG_DELAY_MS, MILLISECONDS,
583 >                          new ArrayBlockingQueue<Runnable>(10));
584 >        final CountDownLatch threadStarted = new CountDownLatch(1);
585 >        final CountDownLatch done = new CountDownLatch(1);
586 >        try {
587 >            assertFalse(p.isTerminating());
588 >            p.execute(new CheckedRunnable() {
589 >                public void realRun() throws InterruptedException {
590 >                    assertFalse(p.isTerminating());
591 >                    threadStarted.countDown();
592 >                    done.await();
593 >                }});
594 >            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
595 >            assertFalse(p.isTerminating());
596 >            done.countDown();
597 >        } finally {
598 >            try { p.shutdown(); } catch (SecurityException ok) { return; }
599 >        }
600 >        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
601 >        assertTrue(p.isTerminated());
602 >        assertFalse(p.isTerminating());
603      }
604  
605      /**
606       * getQueue returns the work queue, which contains queued tasks
607       */
608      public void testGetQueue() throws InterruptedException {
609 <        BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
610 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, q);
611 <        FutureTask[] tasks = new FutureTask[5];
612 <        for (int i = 0; i < 5; i++) {
613 <            tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE);
614 <            p1.execute(tasks[i]);
615 <        }
616 <        try {
617 <            Thread.sleep(SHORT_DELAY_MS);
618 <            BlockingQueue<Runnable> wq = p1.getQueue();
619 <            assertSame(q, wq);
620 <            assertFalse(wq.contains(tasks[0]));
621 <            assertTrue(wq.contains(tasks[4]));
622 <            for (int i = 1; i < 5; ++i)
623 <                tasks[i].cancel(true);
624 <            p1.shutdownNow();
609 >        final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
610 >        final ThreadPoolExecutor p =
611 >            new CustomTPE(1, 1,
612 >                          LONG_DELAY_MS, MILLISECONDS,
613 >                          q);
614 >        final CountDownLatch threadStarted = new CountDownLatch(1);
615 >        final CountDownLatch done = new CountDownLatch(1);
616 >        try {
617 >            FutureTask[] tasks = new FutureTask[5];
618 >            for (int i = 0; i < tasks.length; i++) {
619 >                Callable task = new CheckedCallable<Boolean>() {
620 >                    public Boolean realCall() throws InterruptedException {
621 >                        threadStarted.countDown();
622 >                        assertSame(q, p.getQueue());
623 >                        done.await();
624 >                        return Boolean.TRUE;
625 >                    }};
626 >                tasks[i] = new FutureTask(task);
627 >                p.execute(tasks[i]);
628 >            }
629 >            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
630 >            assertSame(q, p.getQueue());
631 >            assertFalse(q.contains(tasks[0]));
632 >            assertTrue(q.contains(tasks[tasks.length - 1]));
633 >            assertEquals(tasks.length - 1, q.size());
634          } finally {
635 <            joinPool(p1);
635 >            done.countDown();
636 >            joinPool(p);
637          }
638      }
639  
# Line 475 | Line 642 | public class ThreadPoolExecutorSubclassT
642       */
643      public void testRemove() throws InterruptedException {
644          BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
645 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, q);
646 <        FutureTask[] tasks = new FutureTask[5];
647 <        for (int i = 0; i < 5; i++) {
648 <            tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE);
649 <            p1.execute(tasks[i]);
650 <        }
651 <        try {
652 <            Thread.sleep(SHORT_DELAY_MS);
653 <            assertFalse(p1.remove(tasks[0]));
645 >        final ThreadPoolExecutor p =
646 >            new CustomTPE(1, 1,
647 >                          LONG_DELAY_MS, MILLISECONDS,
648 >                          q);
649 >        Runnable[] tasks = new Runnable[6];
650 >        final CountDownLatch threadStarted = new CountDownLatch(1);
651 >        final CountDownLatch done = new CountDownLatch(1);
652 >        try {
653 >            for (int i = 0; i < tasks.length; i++) {
654 >                tasks[i] = new CheckedRunnable() {
655 >                        public void realRun() throws InterruptedException {
656 >                            threadStarted.countDown();
657 >                            done.await();
658 >                        }};
659 >                p.execute(tasks[i]);
660 >            }
661 >            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
662 >            assertFalse(p.remove(tasks[0]));
663              assertTrue(q.contains(tasks[4]));
664              assertTrue(q.contains(tasks[3]));
665 <            assertTrue(p1.remove(tasks[4]));
666 <            assertFalse(p1.remove(tasks[4]));
665 >            assertTrue(p.remove(tasks[4]));
666 >            assertFalse(p.remove(tasks[4]));
667              assertFalse(q.contains(tasks[4]));
668              assertTrue(q.contains(tasks[3]));
669 <            assertTrue(p1.remove(tasks[3]));
669 >            assertTrue(p.remove(tasks[3]));
670              assertFalse(q.contains(tasks[3]));
671          } finally {
672 <            joinPool(p1);
672 >            done.countDown();
673 >            joinPool(p);
674          }
675      }
676  
677      /**
678       * purge removes cancelled tasks from the queue
679       */
680 <    public void testPurge() {
681 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
680 >    public void testPurge() throws InterruptedException {
681 >        final CountDownLatch threadStarted = new CountDownLatch(1);
682 >        final CountDownLatch done = new CountDownLatch(1);
683 >        final BlockingQueue<Runnable> q = new ArrayBlockingQueue<Runnable>(10);
684 >        final ThreadPoolExecutor p =
685 >            new CustomTPE(1, 1,
686 >                          LONG_DELAY_MS, MILLISECONDS,
687 >                          q);
688          FutureTask[] tasks = new FutureTask[5];
689 <        for (int i = 0; i < 5; i++) {
690 <            tasks[i] = new FutureTask(new MediumPossiblyInterruptedRunnable(), Boolean.TRUE);
691 <            p1.execute(tasks[i]);
689 >        try {
690 >            for (int i = 0; i < tasks.length; i++) {
691 >                Callable task = new CheckedCallable<Boolean>() {
692 >                    public Boolean realCall() throws InterruptedException {
693 >                        threadStarted.countDown();
694 >                        done.await();
695 >                        return Boolean.TRUE;
696 >                    }};
697 >                tasks[i] = new FutureTask(task);
698 >                p.execute(tasks[i]);
699 >            }
700 >            assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS));
701 >            assertEquals(tasks.length, p.getTaskCount());
702 >            assertEquals(tasks.length - 1, q.size());
703 >            assertEquals(1L, p.getActiveCount());
704 >            assertEquals(0L, p.getCompletedTaskCount());
705 >            tasks[4].cancel(true);
706 >            tasks[3].cancel(false);
707 >            p.purge();
708 >            assertEquals(tasks.length - 3, q.size());
709 >            assertEquals(tasks.length - 2, p.getTaskCount());
710 >            p.purge();         // Nothing to do
711 >            assertEquals(tasks.length - 3, q.size());
712 >            assertEquals(tasks.length - 2, p.getTaskCount());
713 >        } finally {
714 >            done.countDown();
715 >            joinPool(p);
716          }
510        tasks[4].cancel(true);
511        tasks[3].cancel(true);
512        p1.purge();
513        long count = p1.getTaskCount();
514        assertTrue(count >= 2 && count < 5);
515        joinPool(p1);
717      }
718  
719      /**
720 <     * shutDownNow returns a list containing tasks that were not run
720 >     * shutdownNow returns a list containing tasks that were not run,
721 >     * and those tasks are drained from the queue
722       */
723 <    public void testShutDownNow() {
724 <        ThreadPoolExecutor p1 = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
725 <        List l;
726 <        try {
727 <            for (int i = 0; i < 5; i++)
728 <                p1.execute(new MediumPossiblyInterruptedRunnable());
729 <        }
730 <        finally {
723 >    public void testShutdownNow() throws InterruptedException {
724 >        final int poolSize = 2;
725 >        final int count = 5;
726 >        final AtomicInteger ran = new AtomicInteger(0);
727 >        ThreadPoolExecutor p =
728 >            new CustomTPE(poolSize, poolSize, LONG_DELAY_MS, MILLISECONDS,
729 >                          new ArrayBlockingQueue<Runnable>(10));
730 >        CountDownLatch threadsStarted = new CountDownLatch(poolSize);
731 >        Runnable waiter = new CheckedRunnable() { public void realRun() {
732 >            threadsStarted.countDown();
733              try {
734 <                l = p1.shutdownNow();
735 <            } catch (SecurityException ok) { return; }
736 <        }
737 <        assertTrue(p1.isShutdown());
738 <        assertTrue(l.size() <= 4);
734 >                MILLISECONDS.sleep(2 * LONG_DELAY_MS);
735 >            } catch (InterruptedException success) {}
736 >            ran.getAndIncrement();
737 >        }};
738 >        for (int i = 0; i < count; i++)
739 >            p.execute(waiter);
740 >        assertTrue(threadsStarted.await(LONG_DELAY_MS, MILLISECONDS));
741 >        assertEquals(poolSize, p.getActiveCount());
742 >        assertEquals(0, p.getCompletedTaskCount());
743 >        final List<Runnable> queuedTasks;
744 >        try {
745 >            queuedTasks = p.shutdownNow();
746 >        } catch (SecurityException ok) {
747 >            return; // Allowed in case test doesn't have privs
748 >        }
749 >        assertTrue(p.isShutdown());
750 >        assertTrue(p.getQueue().isEmpty());
751 >        assertEquals(count - poolSize, queuedTasks.size());
752 >        assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS));
753 >        assertTrue(p.isTerminated());
754 >        assertEquals(poolSize, ran.get());
755 >        assertEquals(poolSize, p.getCompletedTaskCount());
756      }
757  
758      // Exception Tests
759  
539
760      /**
761       * Constructor throws if corePoolSize argument is less than zero
762       */
763      public void testConstructor1() {
764          try {
765 <            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
765 >            new CustomTPE(-1, 1, 1L, SECONDS,
766 >                          new ArrayBlockingQueue<Runnable>(10));
767              shouldThrow();
768          } catch (IllegalArgumentException success) {}
769      }
# Line 552 | Line 773 | public class ThreadPoolExecutorSubclassT
773       */
774      public void testConstructor2() {
775          try {
776 <            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
776 >            new CustomTPE(1, -1, 1L, SECONDS,
777 >                          new ArrayBlockingQueue<Runnable>(10));
778              shouldThrow();
779          } catch (IllegalArgumentException success) {}
780      }
# Line 562 | Line 784 | public class ThreadPoolExecutorSubclassT
784       */
785      public void testConstructor3() {
786          try {
787 <            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
787 >            new CustomTPE(1, 0, 1L, SECONDS,
788 >                          new ArrayBlockingQueue<Runnable>(10));
789              shouldThrow();
790          } catch (IllegalArgumentException success) {}
791      }
# Line 572 | Line 795 | public class ThreadPoolExecutorSubclassT
795       */
796      public void testConstructor4() {
797          try {
798 <            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
798 >            new CustomTPE(1, 2, -1L, SECONDS,
799 >                          new ArrayBlockingQueue<Runnable>(10));
800              shouldThrow();
801          } catch (IllegalArgumentException success) {}
802      }
# Line 582 | Line 806 | public class ThreadPoolExecutorSubclassT
806       */
807      public void testConstructor5() {
808          try {
809 <            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
809 >            new CustomTPE(2, 1, 1L, SECONDS,
810 >                          new ArrayBlockingQueue<Runnable>(10));
811              shouldThrow();
812          } catch (IllegalArgumentException success) {}
813      }
# Line 592 | Line 817 | public class ThreadPoolExecutorSubclassT
817       */
818      public void testConstructorNullPointerException() {
819          try {
820 <            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null);
820 >            new CustomTPE(1, 2, 1L, SECONDS, null);
821              shouldThrow();
822          } catch (NullPointerException success) {}
823      }
824  
600
601
825      /**
826       * Constructor throws if corePoolSize argument is less than zero
827       */
828      public void testConstructor6() {
829          try {
830 <            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
830 >            new CustomTPE(-1, 1, 1L, SECONDS,
831 >                          new ArrayBlockingQueue<Runnable>(10),
832 >                          new SimpleThreadFactory());
833              shouldThrow();
834          } catch (IllegalArgumentException success) {}
835      }
# Line 614 | Line 839 | public class ThreadPoolExecutorSubclassT
839       */
840      public void testConstructor7() {
841          try {
842 <            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
842 >            new CustomTPE(1,-1, 1L, SECONDS,
843 >                          new ArrayBlockingQueue<Runnable>(10),
844 >                          new SimpleThreadFactory());
845              shouldThrow();
846          } catch (IllegalArgumentException success) {}
847      }
# Line 624 | Line 851 | public class ThreadPoolExecutorSubclassT
851       */
852      public void testConstructor8() {
853          try {
854 <            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
854 >            new CustomTPE(1, 0, 1L, SECONDS,
855 >                          new ArrayBlockingQueue<Runnable>(10),
856 >                          new SimpleThreadFactory());
857              shouldThrow();
858          } catch (IllegalArgumentException success) {}
859      }
# Line 634 | Line 863 | public class ThreadPoolExecutorSubclassT
863       */
864      public void testConstructor9() {
865          try {
866 <            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
866 >            new CustomTPE(1, 2, -1L, SECONDS,
867 >                          new ArrayBlockingQueue<Runnable>(10),
868 >                          new SimpleThreadFactory());
869              shouldThrow();
870          } catch (IllegalArgumentException success) {}
871      }
# Line 644 | Line 875 | public class ThreadPoolExecutorSubclassT
875       */
876      public void testConstructor10() {
877          try {
878 <            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory());
878 >            new CustomTPE(2, 1, 1L, SECONDS,
879 >                          new ArrayBlockingQueue<Runnable>(10),
880 >                          new SimpleThreadFactory());
881              shouldThrow();
882          } catch (IllegalArgumentException success) {}
883      }
# Line 654 | Line 887 | public class ThreadPoolExecutorSubclassT
887       */
888      public void testConstructorNullPointerException2() {
889          try {
890 <            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory());
890 >            new CustomTPE(1, 2, 1L, SECONDS, null, new SimpleThreadFactory());
891              shouldThrow();
892          } catch (NullPointerException success) {}
893      }
# Line 664 | Line 897 | public class ThreadPoolExecutorSubclassT
897       */
898      public void testConstructorNullPointerException3() {
899          try {
900 <            ThreadFactory f = null;
901 <            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f);
900 >            new CustomTPE(1, 2, 1L, SECONDS,
901 >                          new ArrayBlockingQueue<Runnable>(10),
902 >                          (ThreadFactory) null);
903              shouldThrow();
904          } catch (NullPointerException success) {}
905      }
906  
673
907      /**
908       * Constructor throws if corePoolSize argument is less than zero
909       */
910      public void testConstructor11() {
911          try {
912 <            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
912 >            new CustomTPE(-1, 1, 1L, SECONDS,
913 >                          new ArrayBlockingQueue<Runnable>(10),
914 >                          new NoOpREHandler());
915              shouldThrow();
916          } catch (IllegalArgumentException success) {}
917      }
# Line 686 | Line 921 | public class ThreadPoolExecutorSubclassT
921       */
922      public void testConstructor12() {
923          try {
924 <            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
924 >            new CustomTPE(1, -1, 1L, SECONDS,
925 >                          new ArrayBlockingQueue<Runnable>(10),
926 >                          new NoOpREHandler());
927              shouldThrow();
928          } catch (IllegalArgumentException success) {}
929      }
# Line 696 | Line 933 | public class ThreadPoolExecutorSubclassT
933       */
934      public void testConstructor13() {
935          try {
936 <            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
936 >            new CustomTPE(1, 0, 1L, SECONDS,
937 >                          new ArrayBlockingQueue<Runnable>(10),
938 >                          new NoOpREHandler());
939              shouldThrow();
940          } catch (IllegalArgumentException success) {}
941      }
# Line 706 | Line 945 | public class ThreadPoolExecutorSubclassT
945       */
946      public void testConstructor14() {
947          try {
948 <            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
948 >            new CustomTPE(1, 2, -1L, SECONDS,
949 >                          new ArrayBlockingQueue<Runnable>(10),
950 >                          new NoOpREHandler());
951              shouldThrow();
952          } catch (IllegalArgumentException success) {}
953      }
# Line 716 | Line 957 | public class ThreadPoolExecutorSubclassT
957       */
958      public void testConstructor15() {
959          try {
960 <            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new NoOpREHandler());
960 >            new CustomTPE(2, 1, 1L, SECONDS,
961 >                          new ArrayBlockingQueue<Runnable>(10),
962 >                          new NoOpREHandler());
963              shouldThrow();
964          } catch (IllegalArgumentException success) {}
965      }
# Line 726 | Line 969 | public class ThreadPoolExecutorSubclassT
969       */
970      public void testConstructorNullPointerException4() {
971          try {
972 <            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new NoOpREHandler());
972 >            new CustomTPE(1, 2, 1L, SECONDS,
973 >                          null,
974 >                          new NoOpREHandler());
975              shouldThrow();
976          } catch (NullPointerException success) {}
977      }
# Line 736 | Line 981 | public class ThreadPoolExecutorSubclassT
981       */
982      public void testConstructorNullPointerException5() {
983          try {
984 <            RejectedExecutionHandler r = null;
985 <            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),r);
984 >            new CustomTPE(1, 2, 1L, SECONDS,
985 >                          new ArrayBlockingQueue<Runnable>(10),
986 >                          (RejectedExecutionHandler) null);
987              shouldThrow();
988          } catch (NullPointerException success) {}
989      }
990  
745
991      /**
992       * Constructor throws if corePoolSize argument is less than zero
993       */
994      public void testConstructor16() {
995          try {
996 <            new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
996 >            new CustomTPE(-1, 1, 1L, SECONDS,
997 >                          new ArrayBlockingQueue<Runnable>(10),
998 >                          new SimpleThreadFactory(),
999 >                          new NoOpREHandler());
1000              shouldThrow();
1001          } catch (IllegalArgumentException success) {}
1002      }
# Line 758 | Line 1006 | public class ThreadPoolExecutorSubclassT
1006       */
1007      public void testConstructor17() {
1008          try {
1009 <            new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
1009 >            new CustomTPE(1, -1, 1L, SECONDS,
1010 >                          new ArrayBlockingQueue<Runnable>(10),
1011 >                          new SimpleThreadFactory(),
1012 >                          new NoOpREHandler());
1013              shouldThrow();
1014          } catch (IllegalArgumentException success) {}
1015      }
# Line 768 | Line 1019 | public class ThreadPoolExecutorSubclassT
1019       */
1020      public void testConstructor18() {
1021          try {
1022 <            new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
1022 >            new CustomTPE(1, 0, 1L, SECONDS,
1023 >                          new ArrayBlockingQueue<Runnable>(10),
1024 >                          new SimpleThreadFactory(),
1025 >                          new NoOpREHandler());
1026              shouldThrow();
1027          } catch (IllegalArgumentException success) {}
1028      }
# Line 778 | Line 1032 | public class ThreadPoolExecutorSubclassT
1032       */
1033      public void testConstructor19() {
1034          try {
1035 <            new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
1035 >            new CustomTPE(1, 2, -1L, SECONDS,
1036 >                          new ArrayBlockingQueue<Runnable>(10),
1037 >                          new SimpleThreadFactory(),
1038 >                          new NoOpREHandler());
1039              shouldThrow();
1040          } catch (IllegalArgumentException success) {}
1041      }
# Line 788 | Line 1045 | public class ThreadPoolExecutorSubclassT
1045       */
1046      public void testConstructor20() {
1047          try {
1048 <            new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),new NoOpREHandler());
1048 >            new CustomTPE(2, 1, 1L, SECONDS,
1049 >                          new ArrayBlockingQueue<Runnable>(10),
1050 >                          new SimpleThreadFactory(),
1051 >                          new NoOpREHandler());
1052              shouldThrow();
1053          } catch (IllegalArgumentException success) {}
1054      }
# Line 798 | Line 1058 | public class ThreadPoolExecutorSubclassT
1058       */
1059      public void testConstructorNullPointerException6() {
1060          try {
1061 <            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory(),new NoOpREHandler());
1061 >            new CustomTPE(1, 2, 1L, SECONDS,
1062 >                          null,
1063 >                          new SimpleThreadFactory(),
1064 >                          new NoOpREHandler());
1065              shouldThrow();
1066          } catch (NullPointerException success) {}
1067      }
# Line 808 | Line 1071 | public class ThreadPoolExecutorSubclassT
1071       */
1072      public void testConstructorNullPointerException7() {
1073          try {
1074 <            RejectedExecutionHandler r = null;
1075 <            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),new SimpleThreadFactory(),r);
1074 >            new CustomTPE(1, 2, 1L, SECONDS,
1075 >                          new ArrayBlockingQueue<Runnable>(10),
1076 >                          new SimpleThreadFactory(),
1077 >                          (RejectedExecutionHandler) null);
1078              shouldThrow();
1079          } catch (NullPointerException success) {}
1080      }
# Line 819 | Line 1084 | public class ThreadPoolExecutorSubclassT
1084       */
1085      public void testConstructorNullPointerException8() {
1086          try {
1087 <            ThreadFactory f = null;
1088 <            new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10),f,new NoOpREHandler());
1087 >            new CustomTPE(1, 2, 1L, SECONDS,
1088 >                          new ArrayBlockingQueue<Runnable>(10),
1089 >                          (ThreadFactory) null,
1090 >                          new NoOpREHandler());
1091              shouldThrow();
1092          } catch (NullPointerException success) {}
1093      }
1094  
828
1095      /**
1096       * execute throws RejectedExecutionException if saturated.
1097       */
1098      public void testSaturatedExecute() {
1099 <        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1));
1100 <        try {
1101 <
1102 <            for (int i = 0; i < 5; ++i) {
1103 <                p.execute(new MediumRunnable());
1099 >        ThreadPoolExecutor p =
1100 >            new CustomTPE(1, 1,
1101 >                          LONG_DELAY_MS, MILLISECONDS,
1102 >                          new ArrayBlockingQueue<Runnable>(1));
1103 >        final CountDownLatch done = new CountDownLatch(1);
1104 >        try {
1105 >            Runnable task = new CheckedRunnable() {
1106 >                public void realRun() throws InterruptedException {
1107 >                    done.await();
1108 >                }};
1109 >            for (int i = 0; i < 2; ++i)
1110 >                p.execute(task);
1111 >            for (int i = 0; i < 2; ++i) {
1112 >                try {
1113 >                    p.execute(task);
1114 >                    shouldThrow();
1115 >                } catch (RejectedExecutionException success) {}
1116 >                assertTrue(p.getTaskCount() <= 2);
1117              }
1118 <            shouldThrow();
1119 <        } catch (RejectedExecutionException success) {}
1120 <        joinPool(p);
1118 >        } finally {
1119 >            done.countDown();
1120 >            joinPool(p);
1121 >        }
1122      }
1123  
1124      /**
# Line 846 | Line 1126 | public class ThreadPoolExecutorSubclassT
1126       */
1127      public void testSaturatedExecute2() {
1128          RejectedExecutionHandler h = new CustomTPE.CallerRunsPolicy();
1129 <        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1129 >        ThreadPoolExecutor p = new CustomTPE(1, 1,
1130 >                                             LONG_DELAY_MS, MILLISECONDS,
1131 >                                             new ArrayBlockingQueue<Runnable>(1),
1132 >                                             h);
1133          try {
851
1134              TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
1135 <            for (int i = 0; i < 5; ++i) {
1135 >            for (int i = 0; i < tasks.length; ++i)
1136                  tasks[i] = new TrackedNoOpRunnable();
855            }
1137              TrackedLongRunnable mr = new TrackedLongRunnable();
1138              p.execute(mr);
1139 <            for (int i = 0; i < 5; ++i) {
1139 >            for (int i = 0; i < tasks.length; ++i)
1140                  p.execute(tasks[i]);
1141 <            }
861 <            for (int i = 1; i < 5; ++i) {
1141 >            for (int i = 1; i < tasks.length; ++i)
1142                  assertTrue(tasks[i].done);
863            }
1143              try { p.shutdownNow(); } catch (SecurityException ok) { return; }
1144          } finally {
1145              joinPool(p);
# Line 872 | Line 1151 | public class ThreadPoolExecutorSubclassT
1151       */
1152      public void testSaturatedExecute3() {
1153          RejectedExecutionHandler h = new CustomTPE.DiscardPolicy();
1154 <        ThreadPoolExecutor p = new CustomTPE(1,1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(1), h);
1154 >        ThreadPoolExecutor p =
1155 >            new CustomTPE(1, 1,
1156 >                          LONG_DELAY_MS, MILLISECONDS,
1157 >                          new ArrayBlockingQueue<Runnable>(1),
1158 >                          h);
1159          try {
877
1160              TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5];
1161 <            for (int i = 0; i < 5; ++i) {
1161 >            for (int i = 0; i < tasks.length; ++i)
1162                  tasks[i] = new TrackedNoOpRunnable();
881            }
1163              p.execute(new TrackedLongRunnable());
1164 <            for (int i = 0; i < 5; ++i) {
1165 <                p.execute(tasks[i]);
1166 <            }
1167 <            for (int i = 0; i < 5; ++i) {
887 <                assertFalse(tasks[i].done);
888 <            }
1164 >            for (TrackedNoOpRunnable task : tasks)
1165 >                p.execute(task);
1166 >            for (TrackedNoOpRunnable task : tasks)
1167 >                assertFalse(task.done);
1168              try { p.shutdownNow(); } catch (SecurityException ok) { return; }
1169          } finally {
1170              joinPool(p);
# Line 917 | Line 1196 | public class ThreadPoolExecutorSubclassT
1196       * execute throws RejectedExecutionException if shutdown
1197       */
1198      public void testRejectedExecutionExceptionOnShutdown() {
1199 <        ThreadPoolExecutor tpe =
1199 >        ThreadPoolExecutor p =
1200              new CustomTPE(1,1,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(1));
1201 <        try { tpe.shutdown(); } catch (SecurityException ok) { return; }
1201 >        try { p.shutdown(); } catch (SecurityException ok) { return; }
1202          try {
1203 <            tpe.execute(new NoOpRunnable());
1203 >            p.execute(new NoOpRunnable());
1204              shouldThrow();
1205          } catch (RejectedExecutionException success) {}
1206  
1207 <        joinPool(tpe);
1207 >        joinPool(p);
1208      }
1209  
1210      /**
# Line 962 | Line 1241 | public class ThreadPoolExecutorSubclassT
1241          }
1242      }
1243  
965
1244      /**
1245       * execute using DiscardOldestPolicy drops task on shutdown
1246       */
# Line 980 | Line 1258 | public class ThreadPoolExecutorSubclassT
1258          }
1259      }
1260  
983
1261      /**
1262       * execute(null) throws NPE
1263       */
1264      public void testExecuteNull() {
1265 <        ThreadPoolExecutor tpe = null;
1265 >        ThreadPoolExecutor p =
1266 >            new CustomTPE(1, 2, 1L, SECONDS,
1267 >                          new ArrayBlockingQueue<Runnable>(10));
1268          try {
1269 <            tpe = new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
991 <            tpe.execute(null);
1269 >            p.execute(null);
1270              shouldThrow();
1271          } catch (NullPointerException success) {}
1272  
1273 <        joinPool(tpe);
1273 >        joinPool(p);
1274      }
1275  
1276      /**
1277       * setCorePoolSize of negative value throws IllegalArgumentException
1278       */
1279      public void testCorePoolSizeIllegalArgumentException() {
1280 <        ThreadPoolExecutor tpe =
1280 >        ThreadPoolExecutor p =
1281              new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1282          try {
1283 <            tpe.setCorePoolSize(-1);
1283 >            p.setCorePoolSize(-1);
1284              shouldThrow();
1285          } catch (IllegalArgumentException success) {
1286          } finally {
1287 <            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
1287 >            try { p.shutdown(); } catch (SecurityException ok) { return; }
1288          }
1289 <        joinPool(tpe);
1289 >        joinPool(p);
1290      }
1291  
1292      /**
# Line 1016 | Line 1294 | public class ThreadPoolExecutorSubclassT
1294       * if given a value less the core pool size
1295       */
1296      public void testMaximumPoolSizeIllegalArgumentException() {
1297 <        ThreadPoolExecutor tpe =
1297 >        ThreadPoolExecutor p =
1298              new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1299          try {
1300 <            tpe.setMaximumPoolSize(1);
1300 >            p.setMaximumPoolSize(1);
1301              shouldThrow();
1302          } catch (IllegalArgumentException success) {
1303          } finally {
1304 <            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
1304 >            try { p.shutdown(); } catch (SecurityException ok) { return; }
1305          }
1306 <        joinPool(tpe);
1306 >        joinPool(p);
1307      }
1308  
1309      /**
# Line 1033 | Line 1311 | public class ThreadPoolExecutorSubclassT
1311       * if given a negative value
1312       */
1313      public void testMaximumPoolSizeIllegalArgumentException2() {
1314 <        ThreadPoolExecutor tpe =
1314 >        ThreadPoolExecutor p =
1315              new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1316          try {
1317 <            tpe.setMaximumPoolSize(-1);
1317 >            p.setMaximumPoolSize(-1);
1318              shouldThrow();
1319          } catch (IllegalArgumentException success) {
1320          } finally {
1321 <            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
1321 >            try { p.shutdown(); } catch (SecurityException ok) { return; }
1322          }
1323 <        joinPool(tpe);
1323 >        joinPool(p);
1324      }
1325  
1048
1326      /**
1327       * setKeepAliveTime throws IllegalArgumentException
1328       * when given a negative value
1329       */
1330      public void testKeepAliveTimeIllegalArgumentException() {
1331 <        ThreadPoolExecutor tpe =
1331 >        ThreadPoolExecutor p =
1332              new CustomTPE(2,3,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue<Runnable>(10));
1333  
1334          try {
1335 <            tpe.setKeepAliveTime(-1,MILLISECONDS);
1335 >            p.setKeepAliveTime(-1,MILLISECONDS);
1336              shouldThrow();
1337          } catch (IllegalArgumentException success) {
1338          } finally {
1339 <            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
1339 >            try { p.shutdown(); } catch (SecurityException ok) { return; }
1340          }
1341 <        joinPool(tpe);
1341 >        joinPool(p);
1342      }
1343  
1344      /**
1345       * terminated() is called on termination
1346       */
1347      public void testTerminated() {
1348 <        CustomTPE tpe = new CustomTPE();
1349 <        try { tpe.shutdown(); } catch (SecurityException ok) { return; }
1350 <        assertTrue(tpe.terminatedCalled);
1351 <        joinPool(tpe);
1348 >        CustomTPE p = new CustomTPE();
1349 >        try { p.shutdown(); } catch (SecurityException ok) { return; }
1350 >        assertTrue(p.terminatedCalled());
1351 >        joinPool(p);
1352      }
1353  
1354      /**
1355       * beforeExecute and afterExecute are called when executing task
1356       */
1357      public void testBeforeAfter() throws InterruptedException {
1358 <        CustomTPE tpe = new CustomTPE();
1358 >        CustomTPE p = new CustomTPE();
1359          try {
1360 <            TrackedNoOpRunnable r = new TrackedNoOpRunnable();
1361 <            tpe.execute(r);
1362 <            Thread.sleep(SHORT_DELAY_MS);
1363 <            assertTrue(r.done);
1364 <            assertTrue(tpe.beforeCalled);
1365 <            assertTrue(tpe.afterCalled);
1366 <            try { tpe.shutdown(); } catch (SecurityException ok) { return; }
1360 >            final CountDownLatch done = new CountDownLatch(1);
1361 >            p.execute(new CheckedRunnable() {
1362 >                public void realRun() {
1363 >                    done.countDown();
1364 >                }});
1365 >            await(p.afterCalled);
1366 >            assertEquals(0, done.getCount());
1367 >            assertTrue(p.afterCalled());
1368 >            assertTrue(p.beforeCalled());
1369 >            try { p.shutdown(); } catch (SecurityException ok) { return; }
1370          } finally {
1371 <            joinPool(tpe);
1371 >            joinPool(p);
1372          }
1373      }
1374  
# Line 1134 | Line 1414 | public class ThreadPoolExecutorSubclassT
1414          }
1415      }
1416  
1137
1417      /**
1418       * invokeAny(null) throws NPE
1419       */
# Line 1296 | Line 1575 | public class ThreadPoolExecutorSubclassT
1575          }
1576      }
1577  
1299
1300
1578      /**
1579       * timed invokeAny(null) throws NPE
1580       */
# Line 1484 | Line 1761 | public class ThreadPoolExecutorSubclassT
1761              l.add(new StringTask());
1762              l.add(new StringTask());
1763              List<Future<String>> futures =
1764 <                e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS);
1764 >                e.invokeAll(l, LONG_DELAY_MS, MILLISECONDS);
1765              assertEquals(2, futures.size());
1766              for (Future<String> future : futures)
1767                  assertSame(TEST_STRING, future.get());
# Line 1499 | Line 1776 | public class ThreadPoolExecutorSubclassT
1776      public void testTimedInvokeAll6() throws Exception {
1777          ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1778          try {
1779 <            List<Callable<String>> l = new ArrayList<Callable<String>>();
1780 <            l.add(new StringTask());
1781 <            l.add(Executors.callable(new MediumPossiblyInterruptedRunnable(), TEST_STRING));
1782 <            l.add(new StringTask());
1783 <            List<Future<String>> futures =
1784 <                e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS);
1785 <            assertEquals(3, futures.size());
1786 <            Iterator<Future<String>> it = futures.iterator();
1787 <            Future<String> f1 = it.next();
1788 <            Future<String> f2 = it.next();
1789 <            Future<String> f3 = it.next();
1790 <            assertTrue(f1.isDone());
1791 <            assertTrue(f2.isDone());
1792 <            assertTrue(f3.isDone());
1793 <            assertFalse(f1.isCancelled());
1794 <            assertTrue(f2.isCancelled());
1779 >            for (long timeout = timeoutMillis();;) {
1780 >                List<Callable<String>> tasks = new ArrayList<>();
1781 >                tasks.add(new StringTask("0"));
1782 >                tasks.add(Executors.callable(new LongPossiblyInterruptedRunnable(), TEST_STRING));
1783 >                tasks.add(new StringTask("2"));
1784 >                long startTime = System.nanoTime();
1785 >                List<Future<String>> futures =
1786 >                    e.invokeAll(tasks, timeout, MILLISECONDS);
1787 >                assertEquals(tasks.size(), futures.size());
1788 >                assertTrue(millisElapsedSince(startTime) >= timeout);
1789 >                for (Future future : futures)
1790 >                    assertTrue(future.isDone());
1791 >                assertTrue(futures.get(1).isCancelled());
1792 >                try {
1793 >                    assertEquals("0", futures.get(0).get());
1794 >                    assertEquals("2", futures.get(2).get());
1795 >                    break;
1796 >                } catch (CancellationException retryWithLongerTimeout) {
1797 >                    timeout *= 2;
1798 >                    if (timeout >= LONG_DELAY_MS / 2)
1799 >                        fail("expected exactly one task to be cancelled");
1800 >                }
1801 >            }
1802          } finally {
1803              joinPool(e);
1804          }
# Line 1525 | Line 1809 | public class ThreadPoolExecutorSubclassT
1809       * thread factory fails to create more
1810       */
1811      public void testFailingThreadFactory() throws InterruptedException {
1812 <        ExecutorService e = new CustomTPE(100, 100, LONG_DELAY_MS, MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new FailingThreadFactory());
1813 <        try {
1814 <            for (int k = 0; k < 100; ++k) {
1815 <                e.execute(new NoOpRunnable());
1816 <            }
1817 <            Thread.sleep(LONG_DELAY_MS);
1812 >        final ExecutorService e =
1813 >            new CustomTPE(100, 100,
1814 >                          LONG_DELAY_MS, MILLISECONDS,
1815 >                          new LinkedBlockingQueue<Runnable>(),
1816 >                          new FailingThreadFactory());
1817 >        try {
1818 >            final int TASKS = 100;
1819 >            final CountDownLatch done = new CountDownLatch(TASKS);
1820 >            for (int k = 0; k < TASKS; ++k)
1821 >                e.execute(new CheckedRunnable() {
1822 >                    public void realRun() {
1823 >                        done.countDown();
1824 >                    }});
1825 >            assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS));
1826          } finally {
1827              joinPool(e);
1828          }
# Line 1540 | Line 1832 | public class ThreadPoolExecutorSubclassT
1832       * allowsCoreThreadTimeOut is by default false.
1833       */
1834      public void testAllowsCoreThreadTimeOut() {
1835 <        ThreadPoolExecutor tpe = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1836 <        assertFalse(tpe.allowsCoreThreadTimeOut());
1837 <        joinPool(tpe);
1835 >        ThreadPoolExecutor p = new CustomTPE(2, 2, 1000, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1836 >        assertFalse(p.allowsCoreThreadTimeOut());
1837 >        joinPool(p);
1838      }
1839  
1840      /**
1841       * allowCoreThreadTimeOut(true) causes idle threads to time out
1842       */
1843 <    public void testAllowCoreThreadTimeOut_true() throws InterruptedException {
1844 <        ThreadPoolExecutor tpe = new CustomTPE(2, 10, 10, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1845 <        tpe.allowCoreThreadTimeOut(true);
1846 <        tpe.execute(new NoOpRunnable());
1847 <        try {
1848 <            Thread.sleep(MEDIUM_DELAY_MS);
1849 <            assertEquals(0, tpe.getPoolSize());
1843 >    public void testAllowCoreThreadTimeOut_true() throws Exception {
1844 >        long keepAliveTime = timeoutMillis();
1845 >        final ThreadPoolExecutor p =
1846 >            new CustomTPE(2, 10,
1847 >                          keepAliveTime, MILLISECONDS,
1848 >                          new ArrayBlockingQueue<Runnable>(10));
1849 >        final CountDownLatch threadStarted = new CountDownLatch(1);
1850 >        try {
1851 >            p.allowCoreThreadTimeOut(true);
1852 >            p.execute(new CheckedRunnable() {
1853 >                public void realRun() {
1854 >                    threadStarted.countDown();
1855 >                    assertEquals(1, p.getPoolSize());
1856 >                }});
1857 >            await(threadStarted);
1858 >            delay(keepAliveTime);
1859 >            long startTime = System.nanoTime();
1860 >            while (p.getPoolSize() > 0
1861 >                   && millisElapsedSince(startTime) < LONG_DELAY_MS)
1862 >                Thread.yield();
1863 >            assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS);
1864 >            assertEquals(0, p.getPoolSize());
1865          } finally {
1866 <            joinPool(tpe);
1866 >            joinPool(p);
1867          }
1868      }
1869  
1870      /**
1871       * allowCoreThreadTimeOut(false) causes idle threads not to time out
1872       */
1873 <    public void testAllowCoreThreadTimeOut_false() throws InterruptedException {
1874 <        ThreadPoolExecutor tpe = new CustomTPE(2, 10, 10, MILLISECONDS, new ArrayBlockingQueue<Runnable>(10));
1875 <        tpe.allowCoreThreadTimeOut(false);
1876 <        tpe.execute(new NoOpRunnable());
1877 <        try {
1878 <            Thread.sleep(MEDIUM_DELAY_MS);
1879 <            assertTrue(tpe.getPoolSize() >= 1);
1873 >    public void testAllowCoreThreadTimeOut_false() throws Exception {
1874 >        long keepAliveTime = timeoutMillis();
1875 >        final ThreadPoolExecutor p =
1876 >            new CustomTPE(2, 10,
1877 >                          keepAliveTime, MILLISECONDS,
1878 >                          new ArrayBlockingQueue<Runnable>(10));
1879 >        final CountDownLatch threadStarted = new CountDownLatch(1);
1880 >        try {
1881 >            p.allowCoreThreadTimeOut(false);
1882 >            p.execute(new CheckedRunnable() {
1883 >                public void realRun() throws InterruptedException {
1884 >                    threadStarted.countDown();
1885 >                    assertTrue(p.getPoolSize() >= 1);
1886 >                }});
1887 >            delay(2 * keepAliveTime);
1888 >            assertTrue(p.getPoolSize() >= 1);
1889          } finally {
1890 <            joinPool(tpe);
1890 >            joinPool(p);
1891 >        }
1892 >    }
1893 >
1894 >    /**
1895 >     * get(cancelled task) throws CancellationException
1896 >     * (in part, a test of CustomTPE itself)
1897 >     */
1898 >    public void testGet_cancelled() throws Exception {
1899 >        final ExecutorService e =
1900 >            new CustomTPE(1, 1,
1901 >                          LONG_DELAY_MS, MILLISECONDS,
1902 >                          new LinkedBlockingQueue<Runnable>());
1903 >        try {
1904 >            final CountDownLatch blockerStarted = new CountDownLatch(1);
1905 >            final CountDownLatch done = new CountDownLatch(1);
1906 >            final List<Future<?>> futures = new ArrayList<>();
1907 >            for (int i = 0; i < 2; i++) {
1908 >                Runnable r = new CheckedRunnable() { public void realRun()
1909 >                                                         throws Throwable {
1910 >                    blockerStarted.countDown();
1911 >                    assertTrue(done.await(2 * LONG_DELAY_MS, MILLISECONDS));
1912 >                }};
1913 >                futures.add(e.submit(r));
1914 >            }
1915 >            assertTrue(blockerStarted.await(LONG_DELAY_MS, MILLISECONDS));
1916 >            for (Future<?> future : futures) future.cancel(false);
1917 >            for (Future<?> future : futures) {
1918 >                try {
1919 >                    future.get();
1920 >                    shouldThrow();
1921 >                } catch (CancellationException success) {}
1922 >                try {
1923 >                    future.get(LONG_DELAY_MS, MILLISECONDS);
1924 >                    shouldThrow();
1925 >                } catch (CancellationException success) {}
1926 >                assertTrue(future.isCancelled());
1927 >                assertTrue(future.isDone());
1928 >            }
1929 >            done.countDown();
1930 >        } finally {
1931 >            joinPool(e);
1932          }
1933      }
1934  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines