--- jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java 2010/10/11 07:21:32 1.21 +++ jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java 2015/05/15 17:07:27 1.36 @@ -1,21 +1,43 @@ /* * Written by Doug Lea with assistance from members of JCP JSR-166 * Expert Group and released to the public domain, as explained at - * http://creativecommons.org/licenses/publicdomain + * http://creativecommons.org/publicdomain/zero/1.0/ * Other contributors include Andrew Wright, Jeffrey Hayes, * Pat Fisher, Mike Judd. */ -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.util.concurrent.locks.*; +import static java.util.concurrent.TimeUnit.SECONDS; -import junit.framework.*; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.FutureTask; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.RejectedExecutionHandler; +import java.util.concurrent.RunnableFuture; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.ReentrantLock; + +import junit.framework.Test; +import junit.framework.TestSuite; public class ThreadPoolExecutorSubclassTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { return new TestSuite(ThreadPoolExecutorSubclassTest.class); @@ -37,7 +59,7 @@ public class ThreadPoolExecutorSubclassT CustomTask(final Runnable r, final V res) { if (r == null) throw new NullPointerException(); callable = new Callable() { - public V call() throws Exception { r.run(); return res; }}; + public V call() throws Exception { r.run(); return res; }}; } public boolean isDone() { lock.lock(); try { return done; } finally { lock.unlock() ; } @@ -60,15 +82,13 @@ public class ThreadPoolExecutorSubclassT finally { lock.unlock() ; } } public void run() { - boolean runme; lock.lock(); try { - runme = !done; - if (!runme) - thread = Thread.currentThread(); + if (done) + return; + thread = Thread.currentThread(); } finally { lock.unlock() ; } - if (!runme) return; V v = null; Exception e = null; try { @@ -117,7 +137,6 @@ public class ThreadPoolExecutorSubclassT } } - static class CustomTPE extends ThreadPoolExecutor { protected RunnableFuture newTaskFor(Callable c) { return new CustomTask(c); @@ -164,22 +183,32 @@ public class ThreadPoolExecutorSubclassT workQueue, threadFactory, handler); } - volatile boolean beforeCalled = false; - volatile boolean afterCalled = false; - volatile boolean terminatedCalled = false; + final CountDownLatch beforeCalled = new CountDownLatch(1); + final CountDownLatch afterCalled = new CountDownLatch(1); + final CountDownLatch terminatedCalled = new CountDownLatch(1); + public CustomTPE() { super(1, 1, LONG_DELAY_MS, MILLISECONDS, new SynchronousQueue()); } protected void beforeExecute(Thread t, Runnable r) { - beforeCalled = true; + beforeCalled.countDown(); } protected void afterExecute(Runnable r, Throwable t) { - afterCalled = true; + afterCalled.countDown(); } protected void terminated() { - terminatedCalled = true; + terminatedCalled.countDown(); } + public boolean beforeCalled() { + return beforeCalled.getCount() == 0; + } + public boolean afterCalled() { + return afterCalled.getCount() == 0; + } + public boolean terminatedCalled() { + return terminatedCalled.getCount() == 0; + } } static class FailingThreadFactory implements ThreadFactory { @@ -190,7 +219,6 @@ public class ThreadPoolExecutorSubclassT } } - /** * execute successfully executes a runnable */ @@ -288,12 +316,16 @@ public class ThreadPoolExecutorSubclassT threadProceed.await(); threadDone.countDown(); }}); - assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); + await(threadStarted); assertEquals(0, p.getCompletedTaskCount()); threadProceed.countDown(); threadDone.await(); - Thread.sleep(SHORT_DELAY_MS); - assertEquals(1, p.getCompletedTaskCount()); + long startTime = System.nanoTime(); + while (p.getCompletedTaskCount() != 1) { + if (millisElapsedSince(startTime) > LONG_DELAY_MS) + fail("timed out"); + Thread.yield(); + } } finally { joinPool(p); } @@ -317,7 +349,6 @@ public class ThreadPoolExecutorSubclassT joinPool(p); } - /** * getThreadFactory returns factory in constructor if not set */ @@ -339,7 +370,6 @@ public class ThreadPoolExecutorSubclassT joinPool(p); } - /** * setThreadFactory(null) throws NPE */ @@ -376,7 +406,6 @@ public class ThreadPoolExecutorSubclassT joinPool(p); } - /** * setRejectedExecutionHandler(null) throws NPE */ @@ -391,7 +420,6 @@ public class ThreadPoolExecutorSubclassT } } - /** * getLargestPoolSize increases, but doesn't overestimate, when * multiple threads active @@ -486,7 +514,7 @@ public class ThreadPoolExecutorSubclassT } /** - * isShutDown is false before shutdown, true after + * isShutdown is false before shutdown, true after */ public void testIsShutdown() { @@ -497,7 +525,6 @@ public class ThreadPoolExecutorSubclassT joinPool(p); } - /** * isTerminated is false before termination, true after */ @@ -512,8 +539,8 @@ public class ThreadPoolExecutorSubclassT assertFalse(p.isTerminating()); p.execute(new CheckedRunnable() { public void realRun() throws InterruptedException { - threadStarted.countDown(); assertFalse(p.isTerminating()); + threadStarted.countDown(); done.await(); }}); assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); @@ -541,8 +568,8 @@ public class ThreadPoolExecutorSubclassT assertFalse(p.isTerminating()); p.execute(new CheckedRunnable() { public void realRun() throws InterruptedException { - threadStarted.countDown(); assertFalse(p.isTerminating()); + threadStarted.countDown(); done.await(); }}); assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); @@ -671,9 +698,9 @@ public class ThreadPoolExecutorSubclassT } /** - * shutDownNow returns a list containing tasks that were not run + * shutdownNow returns a list containing tasks that were not run */ - public void testShutDownNow() { + public void testShutdownNow() { ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10)); List l; try { @@ -691,13 +718,13 @@ public class ThreadPoolExecutorSubclassT // Exception Tests - /** * Constructor throws if corePoolSize argument is less than zero */ public void testConstructor1() { try { - new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10)); + new CustomTPE(-1, 1, 1L, SECONDS, + new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -707,7 +734,8 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor2() { try { - new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10)); + new CustomTPE(1, -1, 1L, SECONDS, + new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -717,7 +745,8 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor3() { try { - new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10)); + new CustomTPE(1, 0, 1L, SECONDS, + new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -727,7 +756,8 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor4() { try { - new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue(10)); + new CustomTPE(1, 2, -1L, SECONDS, + new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -737,7 +767,8 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor5() { try { - new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10)); + new CustomTPE(2, 1, 1L, SECONDS, + new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -747,19 +778,19 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructorNullPointerException() { try { - new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null); + new CustomTPE(1, 2, 1L, SECONDS, null); shouldThrow(); } catch (NullPointerException success) {} } - - /** * Constructor throws if corePoolSize argument is less than zero */ public void testConstructor6() { try { - new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory()); + new CustomTPE(-1, 1, 1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -769,7 +800,9 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor7() { try { - new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory()); + new CustomTPE(1,-1, 1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -779,7 +812,9 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor8() { try { - new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory()); + new CustomTPE(1, 0, 1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -789,7 +824,9 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor9() { try { - new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory()); + new CustomTPE(1, 2, -1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -799,7 +836,9 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor10() { try { - new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory()); + new CustomTPE(2, 1, 1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -809,7 +848,7 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructorNullPointerException2() { try { - new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory()); + new CustomTPE(1, 2, 1L, SECONDS, null, new SimpleThreadFactory()); shouldThrow(); } catch (NullPointerException success) {} } @@ -819,19 +858,21 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructorNullPointerException3() { try { - ThreadFactory f = null; - new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue(10),f); + new CustomTPE(1, 2, 1L, SECONDS, + new ArrayBlockingQueue(10), + (ThreadFactory) null); shouldThrow(); } catch (NullPointerException success) {} } - /** * Constructor throws if corePoolSize argument is less than zero */ public void testConstructor11() { try { - new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new NoOpREHandler()); + new CustomTPE(-1, 1, 1L, SECONDS, + new ArrayBlockingQueue(10), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -841,7 +882,9 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor12() { try { - new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new NoOpREHandler()); + new CustomTPE(1, -1, 1L, SECONDS, + new ArrayBlockingQueue(10), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -851,7 +894,9 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor13() { try { - new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new NoOpREHandler()); + new CustomTPE(1, 0, 1L, SECONDS, + new ArrayBlockingQueue(10), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -861,7 +906,9 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor14() { try { - new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue(10),new NoOpREHandler()); + new CustomTPE(1, 2, -1L, SECONDS, + new ArrayBlockingQueue(10), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -871,7 +918,9 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor15() { try { - new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new NoOpREHandler()); + new CustomTPE(2, 1, 1L, SECONDS, + new ArrayBlockingQueue(10), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -881,7 +930,9 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructorNullPointerException4() { try { - new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new NoOpREHandler()); + new CustomTPE(1, 2, 1L, SECONDS, + null, + new NoOpREHandler()); shouldThrow(); } catch (NullPointerException success) {} } @@ -891,19 +942,22 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructorNullPointerException5() { try { - RejectedExecutionHandler r = null; - new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue(10),r); + new CustomTPE(1, 2, 1L, SECONDS, + new ArrayBlockingQueue(10), + (RejectedExecutionHandler) null); shouldThrow(); } catch (NullPointerException success) {} } - /** * Constructor throws if corePoolSize argument is less than zero */ public void testConstructor16() { try { - new CustomTPE(-1,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory(),new NoOpREHandler()); + new CustomTPE(-1, 1, 1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory(), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -913,7 +967,10 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor17() { try { - new CustomTPE(1,-1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory(),new NoOpREHandler()); + new CustomTPE(1, -1, 1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory(), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -923,7 +980,10 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor18() { try { - new CustomTPE(1,0,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory(),new NoOpREHandler()); + new CustomTPE(1, 0, 1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory(), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -933,7 +993,10 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor19() { try { - new CustomTPE(1,2,-1L,MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory(),new NoOpREHandler()); + new CustomTPE(1, 2, -1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory(), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -943,7 +1006,10 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructor20() { try { - new CustomTPE(2,1,LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10),new SimpleThreadFactory(),new NoOpREHandler()); + new CustomTPE(2, 1, 1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory(), + new NoOpREHandler()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -953,7 +1019,10 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructorNullPointerException6() { try { - new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,null,new SimpleThreadFactory(),new NoOpREHandler()); + new CustomTPE(1, 2, 1L, SECONDS, + null, + new SimpleThreadFactory(), + new NoOpREHandler()); shouldThrow(); } catch (NullPointerException success) {} } @@ -963,8 +1032,10 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructorNullPointerException7() { try { - RejectedExecutionHandler r = null; - new CustomTPE(1,2,LONG_DELAY_MS, MILLISECONDS,new ArrayBlockingQueue(10),new SimpleThreadFactory(),r); + new CustomTPE(1, 2, 1L, SECONDS, + new ArrayBlockingQueue(10), + new SimpleThreadFactory(), + (RejectedExecutionHandler) null); shouldThrow(); } catch (NullPointerException success) {} } @@ -974,8 +1045,7 @@ public class ThreadPoolExecutorSubclassT */ public void testConstructorNullPointerException8() { try { - new CustomTPE(1, 2, - LONG_DELAY_MS, MILLISECONDS, + new CustomTPE(1, 2, 1L, SECONDS, new ArrayBlockingQueue(10), (ThreadFactory) null, new NoOpREHandler()); @@ -983,7 +1053,6 @@ public class ThreadPoolExecutorSubclassT } catch (NullPointerException success) {} } - /** * execute throws RejectedExecutionException if saturated. */ @@ -1133,7 +1202,6 @@ public class ThreadPoolExecutorSubclassT } } - /** * execute using DiscardOldestPolicy drops task on shutdown */ @@ -1151,7 +1219,6 @@ public class ThreadPoolExecutorSubclassT } } - /** * execute(null) throws NPE */ @@ -1216,7 +1283,6 @@ public class ThreadPoolExecutorSubclassT joinPool(p); } - /** * setKeepAliveTime throws IllegalArgumentException * when given a negative value @@ -1241,7 +1307,7 @@ public class ThreadPoolExecutorSubclassT public void testTerminated() { CustomTPE p = new CustomTPE(); try { p.shutdown(); } catch (SecurityException ok) { return; } - assertTrue(p.terminatedCalled); + assertTrue(p.terminatedCalled()); joinPool(p); } @@ -1251,12 +1317,15 @@ public class ThreadPoolExecutorSubclassT public void testBeforeAfter() throws InterruptedException { CustomTPE p = new CustomTPE(); try { - TrackedNoOpRunnable r = new TrackedNoOpRunnable(); - p.execute(r); - Thread.sleep(SHORT_DELAY_MS); - assertTrue(r.done); - assertTrue(p.beforeCalled); - assertTrue(p.afterCalled); + final CountDownLatch done = new CountDownLatch(1); + p.execute(new CheckedRunnable() { + public void realRun() { + done.countDown(); + }}); + await(p.afterCalled); + assertEquals(0, done.getCount()); + assertTrue(p.afterCalled()); + assertTrue(p.beforeCalled()); try { p.shutdown(); } catch (SecurityException ok) { return; } } finally { joinPool(p); @@ -1305,7 +1374,6 @@ public class ThreadPoolExecutorSubclassT } } - /** * invokeAny(null) throws NPE */ @@ -1467,8 +1535,6 @@ public class ThreadPoolExecutorSubclassT } } - - /** * timed invokeAny(null) throws NPE */ @@ -1676,16 +1742,11 @@ public class ThreadPoolExecutorSubclassT l.add(new StringTask()); List> futures = e.invokeAll(l, SHORT_DELAY_MS, MILLISECONDS); - assertEquals(3, futures.size()); - Iterator> it = futures.iterator(); - Future f1 = it.next(); - Future f2 = it.next(); - Future f3 = it.next(); - assertTrue(f1.isDone()); - assertTrue(f2.isDone()); - assertTrue(f3.isDone()); - assertFalse(f1.isCancelled()); - assertTrue(f2.isCancelled()); + assertEquals(l.size(), futures.size()); + for (Future future : futures) + assertTrue(future.isDone()); + assertFalse(futures.get(0).isCancelled()); + assertTrue(futures.get(1).isCancelled()); } finally { joinPool(e); } @@ -1728,9 +1789,10 @@ public class ThreadPoolExecutorSubclassT * allowCoreThreadTimeOut(true) causes idle threads to time out */ public void testAllowCoreThreadTimeOut_true() throws Exception { + long coreThreadTimeOut = SHORT_DELAY_MS; final ThreadPoolExecutor p = new CustomTPE(2, 10, - SHORT_DELAY_MS, MILLISECONDS, + coreThreadTimeOut, MILLISECONDS, new ArrayBlockingQueue(10)); final CountDownLatch threadStarted = new CountDownLatch(1); try { @@ -1740,12 +1802,13 @@ public class ThreadPoolExecutorSubclassT threadStarted.countDown(); assertEquals(1, p.getPoolSize()); }}); - assertTrue(threadStarted.await(SMALL_DELAY_MS, MILLISECONDS)); - for (int i = 0; i < (MEDIUM_DELAY_MS/10); i++) { - if (p.getPoolSize() == 0) - break; - Thread.sleep(10); - } + await(threadStarted); + delay(coreThreadTimeOut); + long startTime = System.nanoTime(); + while (p.getPoolSize() > 0 + && millisElapsedSince(startTime) < LONG_DELAY_MS) + Thread.yield(); + assertTrue(millisElapsedSince(startTime) < LONG_DELAY_MS); assertEquals(0, p.getPoolSize()); } finally { joinPool(p); @@ -1756,9 +1819,10 @@ public class ThreadPoolExecutorSubclassT * allowCoreThreadTimeOut(false) causes idle threads not to time out */ public void testAllowCoreThreadTimeOut_false() throws Exception { + long coreThreadTimeOut = SHORT_DELAY_MS; final ThreadPoolExecutor p = new CustomTPE(2, 10, - SHORT_DELAY_MS, MILLISECONDS, + coreThreadTimeOut, MILLISECONDS, new ArrayBlockingQueue(10)); final CountDownLatch threadStarted = new CountDownLatch(1); try { @@ -1768,7 +1832,7 @@ public class ThreadPoolExecutorSubclassT threadStarted.countDown(); assertTrue(p.getPoolSize() >= 1); }}); - Thread.sleep(SMALL_DELAY_MS); + delay(2 * coreThreadTimeOut); assertTrue(p.getPoolSize() >= 1); } finally { joinPool(p);