--- jsr166/src/test/tck/ThreadPoolExecutorTest.java 2011/03/15 19:47:07 1.40 +++ jsr166/src/test/tck/ThreadPoolExecutorTest.java 2015/05/15 17:07:27 1.52 @@ -6,35 +6,66 @@ * Pat Fisher, Mike Judd. */ -import java.util.concurrent.*; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import java.util.concurrent.atomic.*; -import junit.framework.*; -import java.util.*; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +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.SynchronousQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import junit.framework.Test; +import junit.framework.TestSuite; public class ThreadPoolExecutorTest extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { return new TestSuite(ThreadPoolExecutorTest.class); } static class ExtendedTPE extends ThreadPoolExecutor { - 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 ExtendedTPE() { 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; } } @@ -46,7 +77,6 @@ public class ThreadPoolExecutorTest exte } } - /** * execute successfully executes a runnable */ @@ -150,12 +180,16 @@ public class ThreadPoolExecutorTest exte 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); } @@ -185,7 +219,6 @@ public class ThreadPoolExecutorTest exte joinPool(p); } - /** * getThreadFactory returns factory in constructor if not set */ @@ -215,7 +248,6 @@ public class ThreadPoolExecutorTest exte joinPool(p); } - /** * setThreadFactory(null) throws NPE */ @@ -262,7 +294,6 @@ public class ThreadPoolExecutorTest exte joinPool(p); } - /** * setRejectedExecutionHandler(null) throws NPE */ @@ -280,7 +311,6 @@ public class ThreadPoolExecutorTest exte } } - /** * getLargestPoolSize increases, but doesn't overestimate, when * multiple threads active @@ -378,7 +408,7 @@ public class ThreadPoolExecutorTest exte } /** - * isShutDown is false before shutdown, true after + * isShutdown is false before shutdown, true after */ public void testIsShutdown() { final ThreadPoolExecutor p = @@ -391,6 +421,35 @@ public class ThreadPoolExecutorTest exte joinPool(p); } + /** + * awaitTermination on a non-shutdown pool times out + */ + public void testAwaitTermination_timesOut() throws InterruptedException { + final ThreadPoolExecutor p = + new ThreadPoolExecutor(1, 1, + LONG_DELAY_MS, MILLISECONDS, + new ArrayBlockingQueue(10)); + assertFalse(p.isTerminated()); + assertFalse(p.awaitTermination(Long.MIN_VALUE, NANOSECONDS)); + assertFalse(p.awaitTermination(Long.MIN_VALUE, MILLISECONDS)); + assertFalse(p.awaitTermination(-1L, NANOSECONDS)); + assertFalse(p.awaitTermination(-1L, MILLISECONDS)); + assertFalse(p.awaitTermination(0L, NANOSECONDS)); + assertFalse(p.awaitTermination(0L, MILLISECONDS)); + long timeoutNanos = 999999L; + long startTime = System.nanoTime(); + assertFalse(p.awaitTermination(timeoutNanos, NANOSECONDS)); + assertTrue(System.nanoTime() - startTime >= timeoutNanos); + assertFalse(p.isTerminated()); + startTime = System.nanoTime(); + long timeoutMillis = timeoutMillis(); + assertFalse(p.awaitTermination(timeoutMillis, MILLISECONDS)); + assertTrue(millisElapsedSince(startTime) >= timeoutMillis); + assertFalse(p.isTerminated()); + p.shutdown(); + assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); + assertTrue(p.isTerminated()); + } /** * isTerminated is false before termination, true after @@ -564,9 +623,9 @@ public class ThreadPoolExecutorTest exte } /** - * 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() { final ThreadPoolExecutor p = new ThreadPoolExecutor(1, 1, LONG_DELAY_MS, MILLISECONDS, @@ -587,14 +646,12 @@ public class ThreadPoolExecutorTest exte // Exception Tests - /** * Constructor throws if corePoolSize argument is less than zero */ public void testConstructor1() { try { - new ThreadPoolExecutor(-1, 1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(-1, 1, 1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} @@ -605,8 +662,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor2() { try { - new ThreadPoolExecutor(1, -1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, -1, 1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} @@ -617,8 +673,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor3() { try { - new ThreadPoolExecutor(1, 0, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 0, 1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} @@ -629,8 +684,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor4() { try { - new ThreadPoolExecutor(1, 2, - -1L, MILLISECONDS, + new ThreadPoolExecutor(1, 2, -1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} @@ -641,8 +695,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor5() { try { - new ThreadPoolExecutor(2, 1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(2, 1, 1L, SECONDS, new ArrayBlockingQueue(10)); shouldThrow(); } catch (IllegalArgumentException success) {} @@ -653,22 +706,18 @@ public class ThreadPoolExecutorTest exte */ public void testConstructorNullPointerException() { try { - new ThreadPoolExecutor(1, 2, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 2, 1L, SECONDS, (BlockingQueue) null); shouldThrow(); } catch (NullPointerException success) {} } - - /** * Constructor throws if corePoolSize argument is less than zero */ public void testConstructor6() { try { - new ThreadPoolExecutor(-1, 1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(-1, 1, 1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); @@ -680,8 +729,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor7() { try { - new ThreadPoolExecutor(1, -1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, -1, 1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); @@ -693,8 +741,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor8() { try { - new ThreadPoolExecutor(1, 0, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 0, 1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); @@ -706,8 +753,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor9() { try { - new ThreadPoolExecutor(1, 2, - -1L, MILLISECONDS, + new ThreadPoolExecutor(1, 2, -1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); @@ -719,8 +765,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor10() { try { - new ThreadPoolExecutor(2, 1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(2, 1, 1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory()); shouldThrow(); @@ -732,8 +777,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructorNullPointerException2() { try { - new ThreadPoolExecutor(1, 2, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 2, 1L, SECONDS, (BlockingQueue) null, new SimpleThreadFactory()); shouldThrow(); @@ -745,22 +789,19 @@ public class ThreadPoolExecutorTest exte */ public void testConstructorNullPointerException3() { try { - new ThreadPoolExecutor(1, 2, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(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 ThreadPoolExecutor(-1, 1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(-1, 1, 1L, SECONDS, new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); @@ -772,8 +813,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor12() { try { - new ThreadPoolExecutor(1, -1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, -1, 1L, SECONDS, new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); @@ -785,8 +825,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor13() { try { - new ThreadPoolExecutor(1, 0, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 0, 1L, SECONDS, new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); @@ -798,8 +837,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor14() { try { - new ThreadPoolExecutor(1, 2, - -1L, MILLISECONDS, + new ThreadPoolExecutor(1, 2, -1L, SECONDS, new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); @@ -811,8 +849,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor15() { try { - new ThreadPoolExecutor(2, 1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(2, 1, 1L, SECONDS, new ArrayBlockingQueue(10), new NoOpREHandler()); shouldThrow(); @@ -824,8 +861,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructorNullPointerException4() { try { - new ThreadPoolExecutor(1, 2, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 2, 1L, SECONDS, (BlockingQueue) null, new NoOpREHandler()); shouldThrow(); @@ -837,22 +873,19 @@ public class ThreadPoolExecutorTest exte */ public void testConstructorNullPointerException5() { try { - new ThreadPoolExecutor(1, 2, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(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 ThreadPoolExecutor(-1, 1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(-1, 1, 1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory(), new NoOpREHandler()); @@ -865,8 +898,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor17() { try { - new ThreadPoolExecutor(1, -1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, -1, 1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory(), new NoOpREHandler()); @@ -879,8 +911,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor18() { try { - new ThreadPoolExecutor(1, 0, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 0, 1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory(), new NoOpREHandler()); @@ -893,8 +924,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor19() { try { - new ThreadPoolExecutor(1, 2, - -1L, MILLISECONDS, + new ThreadPoolExecutor(1, 2, -1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory(), new NoOpREHandler()); @@ -907,8 +937,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructor20() { try { - new ThreadPoolExecutor(2, 1, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(2, 1, 1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory(), new NoOpREHandler()); @@ -921,8 +950,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructorNullPointerException6() { try { - new ThreadPoolExecutor(1, 2, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 2, 1L, SECONDS, (BlockingQueue) null, new SimpleThreadFactory(), new NoOpREHandler()); @@ -935,8 +963,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructorNullPointerException7() { try { - new ThreadPoolExecutor(1, 2, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 2, 1L, SECONDS, new ArrayBlockingQueue(10), new SimpleThreadFactory(), (RejectedExecutionHandler) null); @@ -949,8 +976,7 @@ public class ThreadPoolExecutorTest exte */ public void testConstructorNullPointerException8() { try { - new ThreadPoolExecutor(1, 2, - LONG_DELAY_MS, MILLISECONDS, + new ThreadPoolExecutor(1, 2, 1L, SECONDS, new ArrayBlockingQueue(10), (ThreadFactory) null, new NoOpREHandler()); @@ -1212,7 +1238,6 @@ public class ThreadPoolExecutorTest exte } } - /** * execute using DiscardOldestPolicy drops task on shutdown */ @@ -1234,7 +1259,6 @@ public class ThreadPoolExecutorTest exte } } - /** * execute(null) throws NPE */ @@ -1307,7 +1331,6 @@ public class ThreadPoolExecutorTest exte joinPool(p); } - /** * setKeepAliveTime throws IllegalArgumentException * when given a negative value @@ -1333,7 +1356,7 @@ public class ThreadPoolExecutorTest exte public void testTerminated() { ExtendedTPE p = new ExtendedTPE(); try { p.shutdown(); } catch (SecurityException ok) { return; } - assertTrue(p.terminatedCalled); + assertTrue(p.terminatedCalled()); joinPool(p); } @@ -1343,12 +1366,15 @@ public class ThreadPoolExecutorTest exte public void testBeforeAfter() throws InterruptedException { ExtendedTPE p = new ExtendedTPE(); 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); @@ -1406,7 +1432,6 @@ public class ThreadPoolExecutorTest exte } } - /** * invokeAny(null) throws NPE */ @@ -1600,8 +1625,6 @@ public class ThreadPoolExecutorTest exte } } - - /** * timed invokeAny(null) throws NPE */ @@ -1848,16 +1871,11 @@ public class ThreadPoolExecutorTest exte 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); } @@ -1903,24 +1921,26 @@ public class ThreadPoolExecutorTest exte * allowCoreThreadTimeOut(true) causes idle threads to time out */ public void testAllowCoreThreadTimeOut_true() throws Exception { + long coreThreadTimeOut = SHORT_DELAY_MS; final ThreadPoolExecutor p = new ThreadPoolExecutor(2, 10, - SHORT_DELAY_MS, MILLISECONDS, + coreThreadTimeOut, MILLISECONDS, new ArrayBlockingQueue(10)); final CountDownLatch threadStarted = new CountDownLatch(1); try { p.allowCoreThreadTimeOut(true); p.execute(new CheckedRunnable() { - public void realRun() throws InterruptedException { + public void realRun() { 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); @@ -1931,9 +1951,10 @@ public class ThreadPoolExecutorTest exte * allowCoreThreadTimeOut(false) causes idle threads not to time out */ public void testAllowCoreThreadTimeOut_false() throws Exception { + long coreThreadTimeOut = SHORT_DELAY_MS; final ThreadPoolExecutor p = new ThreadPoolExecutor(2, 10, - SHORT_DELAY_MS, MILLISECONDS, + coreThreadTimeOut, MILLISECONDS, new ArrayBlockingQueue(10)); final CountDownLatch threadStarted = new CountDownLatch(1); try { @@ -1943,7 +1964,7 @@ public class ThreadPoolExecutorTest exte threadStarted.countDown(); assertTrue(p.getPoolSize() >= 1); }}); - Thread.sleep(SMALL_DELAY_MS); + delay(2 * coreThreadTimeOut); assertTrue(p.getPoolSize() >= 1); } finally { joinPool(p); @@ -1977,7 +1998,7 @@ public class ThreadPoolExecutorTest exte // enough time to run all tasks assertTrue(done.await(nTasks * SHORT_DELAY_MS, MILLISECONDS)); } finally { - p.shutdown(); + joinPool(p); } }