--- jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java 2017/01/04 06:09:58 1.97 +++ jsr166/src/test/tck/ThreadPoolExecutorSubclassTest.java 2017/07/17 22:27:31 1.100 @@ -10,6 +10,8 @@ import static java.util.concurrent.TimeU import static java.util.concurrent.TimeUnit.SECONDS; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.List; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; @@ -21,11 +23,11 @@ import java.util.concurrent.ExecutorServ 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.ThreadLocalRandom; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeUnit; @@ -238,7 +240,7 @@ public class ThreadPoolExecutorSubclassT final Runnable task = new CheckedRunnable() { public void realRun() { done.countDown(); }}; p.execute(task); - assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS)); + await(done); } } @@ -332,13 +334,13 @@ public class ThreadPoolExecutorSubclassT public void realRun() throws InterruptedException { threadStarted.countDown(); assertEquals(0, p.getCompletedTaskCount()); - threadProceed.await(); + await(threadProceed); threadDone.countDown(); }}); await(threadStarted); assertEquals(0, p.getCompletedTaskCount()); threadProceed.countDown(); - threadDone.await(); + await(threadDone); long startTime = System.nanoTime(); while (p.getCompletedTaskCount() != 1) { if (millisElapsedSince(startTime) > LONG_DELAY_MS) @@ -1129,88 +1131,71 @@ public class ThreadPoolExecutorSubclassT } /** - * execute throws RejectedExecutionException if saturated. + * Submitted tasks are rejected when saturated or shutdown */ - public void testSaturatedExecute() { - final CountDownLatch done = new CountDownLatch(1); + public void testSubmittedTasksRejectedWhenSaturatedOrShutdown() throws InterruptedException { final ThreadPoolExecutor p = new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(1)); - try (PoolCleaner cleaner = cleaner(p, done)) { - Runnable task = new CheckedRunnable() { - public void realRun() throws InterruptedException { - await(done); - }}; - for (int i = 0; i < 2; ++i) - p.execute(task); - for (int i = 0; i < 2; ++i) { + final int saturatedSize = saturatedSize(p); + final ThreadLocalRandom rnd = ThreadLocalRandom.current(); + final CountDownLatch threadsStarted = new CountDownLatch(p.getMaximumPoolSize()); + final CountDownLatch done = new CountDownLatch(1); + final Runnable r = () -> { + threadsStarted.countDown(); + for (;;) { try { - p.execute(task); - shouldThrow(); - } catch (RejectedExecutionException success) {} - assertTrue(p.getTaskCount() <= 2); - } - } - } + done.await(); + return; + } catch (InterruptedException shutdownNowDeliberatelyIgnored) {} + }}; + final Callable c = () -> { + threadsStarted.countDown(); + for (;;) { + try { + done.await(); + return Boolean.TRUE; + } catch (InterruptedException shutdownNowDeliberatelyIgnored) {} + }}; + final boolean shutdownNow = rnd.nextBoolean(); - /** - * executor using CallerRunsPolicy runs task if saturated. - */ - public void testSaturatedExecute2() { - final CountDownLatch done = new CountDownLatch(1); - final ThreadPoolExecutor p = - new CustomTPE(1, 1, - LONG_DELAY_MS, MILLISECONDS, - new ArrayBlockingQueue(1), - new CustomTPE.CallerRunsPolicy()); try (PoolCleaner cleaner = cleaner(p, done)) { - Runnable blocker = new CheckedRunnable() { - public void realRun() throws InterruptedException { - await(done); - }}; - p.execute(blocker); - TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5]; - for (int i = 0; i < tasks.length; i++) - tasks[i] = new TrackedNoOpRunnable(); - for (int i = 0; i < tasks.length; i++) - p.execute(tasks[i]); - for (int i = 1; i < tasks.length; i++) - assertTrue(tasks[i].done); - assertFalse(tasks[0].done); // waiting in queue - } - } + // saturate + for (int i = saturatedSize; i--> 0; ) { + switch (rnd.nextInt(4)) { + case 0: p.execute(r); break; + case 1: assertFalse(p.submit(r).isDone()); break; + case 2: assertFalse(p.submit(r, Boolean.TRUE).isDone()); break; + case 3: assertFalse(p.submit(c).isDone()); break; + } + } - /** - * executor using DiscardPolicy drops task if saturated. - */ - public void testSaturatedExecute3() { - final TrackedNoOpRunnable[] tasks = new TrackedNoOpRunnable[5]; - for (int i = 0; i < tasks.length; ++i) - tasks[i] = new TrackedNoOpRunnable(); - final CountDownLatch done = new CountDownLatch(1); - final ThreadPoolExecutor p = - new CustomTPE(1, 1, - LONG_DELAY_MS, MILLISECONDS, - new ArrayBlockingQueue(1), - new CustomTPE.DiscardPolicy()); - try (PoolCleaner cleaner = cleaner(p, done)) { - p.execute(awaiter(done)); + await(threadsStarted); + assertTaskSubmissionsAreRejected(p); + + if (shutdownNow) + p.shutdownNow(); + else + p.shutdown(); + // Pool is shutdown, but not yet terminated + assertTaskSubmissionsAreRejected(p); + assertFalse(p.isTerminated()); + + done.countDown(); // release blocking tasks + assertTrue(p.awaitTermination(LONG_DELAY_MS, MILLISECONDS)); - for (TrackedNoOpRunnable task : tasks) - p.execute(task); - for (int i = 1; i < tasks.length; i++) - assertFalse(tasks[i].done); - } - for (int i = 1; i < tasks.length; i++) - assertFalse(tasks[i].done); - assertTrue(tasks[0].done); // was waiting in queue + assertTaskSubmissionsAreRejected(p); + } + assertEquals(saturatedSize(p) + - (shutdownNow ? p.getQueue().remainingCapacity() : 0), + p.getCompletedTaskCount()); } /** * executor using DiscardOldestPolicy drops oldest task if saturated. */ - public void testSaturatedExecute4() { + public void testSaturatedExecute_DiscardOldestPolicy() { final CountDownLatch done = new CountDownLatch(1); LatchAwaiter r1 = awaiter(done); LatchAwaiter r2 = awaiter(done); @@ -1219,7 +1204,7 @@ public class ThreadPoolExecutorSubclassT new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(1), - new CustomTPE.DiscardOldestPolicy()); + new ThreadPoolExecutor.DiscardOldestPolicy()); try (PoolCleaner cleaner = cleaner(p, done)) { assertEquals(LatchAwaiter.NEW, r1.state); assertEquals(LatchAwaiter.NEW, r2.state); @@ -1237,57 +1222,6 @@ public class ThreadPoolExecutorSubclassT } /** - * execute throws RejectedExecutionException if shutdown - */ - public void testRejectedExecutionExceptionOnShutdown() { - final ThreadPoolExecutor p = - new CustomTPE(1, 1, - LONG_DELAY_MS, MILLISECONDS, - new ArrayBlockingQueue(1)); - try { p.shutdown(); } catch (SecurityException ok) { return; } - try (PoolCleaner cleaner = cleaner(p)) { - try { - p.execute(new NoOpRunnable()); - shouldThrow(); - } catch (RejectedExecutionException success) {} - } - } - - /** - * execute using CallerRunsPolicy drops task on shutdown - */ - public void testCallerRunsOnShutdown() { - final ThreadPoolExecutor p = - new CustomTPE(1, 1, - LONG_DELAY_MS, MILLISECONDS, - new ArrayBlockingQueue(1), - new CustomTPE.CallerRunsPolicy()); - try { p.shutdown(); } catch (SecurityException ok) { return; } - try (PoolCleaner cleaner = cleaner(p)) { - TrackedNoOpRunnable r = new TrackedNoOpRunnable(); - p.execute(r); - assertFalse(r.done); - } - } - - /** - * execute using DiscardPolicy drops task on shutdown - */ - public void testDiscardOnShutdown() { - final ThreadPoolExecutor p = - new CustomTPE(1, 1, - LONG_DELAY_MS, MILLISECONDS, - new ArrayBlockingQueue(1), - new CustomTPE.DiscardPolicy()); - try { p.shutdown(); } catch (SecurityException ok) { return; } - try (PoolCleaner cleaner = cleaner(p)) { - TrackedNoOpRunnable r = new TrackedNoOpRunnable(); - p.execute(r); - assertFalse(r.done); - } - } - - /** * execute using DiscardOldestPolicy drops task on shutdown */ public void testDiscardOldestOnShutdown() { @@ -1295,7 +1229,7 @@ public class ThreadPoolExecutorSubclassT new CustomTPE(1, 1, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(1), - new CustomTPE.DiscardOldestPolicy()); + new ThreadPoolExecutor.DiscardOldestPolicy()); try { p.shutdown(); } catch (SecurityException ok) { return; } try (PoolCleaner cleaner = cleaner(p)) { @@ -1306,18 +1240,15 @@ public class ThreadPoolExecutorSubclassT } /** - * execute(null) throws NPE + * Submitting null tasks throws NullPointerException */ - public void testExecuteNull() { + public void testNullTaskSubmission() { final ThreadPoolExecutor p = new CustomTPE(1, 2, 1L, SECONDS, new ArrayBlockingQueue(10)); try (PoolCleaner cleaner = cleaner(p)) { - try { - p.execute(null); - shouldThrow(); - } catch (NullPointerException success) {} + assertNullTaskSubmissionThrowsNullPointerException(p); } } @@ -1464,7 +1395,7 @@ public class ThreadPoolExecutorSubclassT } /** - * invokeAny(null) throws NPE + * invokeAny(null) throws NullPointerException */ public void testInvokeAny1() throws Exception { final ExecutorService e = @@ -1480,7 +1411,7 @@ public class ThreadPoolExecutorSubclassT } /** - * invokeAny(empty collection) throws IAE + * invokeAny(empty collection) throws IllegalArgumentException */ public void testInvokeAny2() throws Exception { final ExecutorService e = @@ -1570,15 +1501,17 @@ public class ThreadPoolExecutorSubclassT } /** - * invokeAll(empty collection) returns empty collection + * invokeAll(empty collection) returns empty list */ public void testInvokeAll2() throws Exception { final ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10)); + final Collection> emptyCollection + = Collections.emptyList(); try (PoolCleaner cleaner = cleaner(e)) { - List> r = e.invokeAll(new ArrayList>()); + List> r = e.invokeAll(emptyCollection); assertTrue(r.isEmpty()); } } @@ -1653,7 +1586,7 @@ public class ThreadPoolExecutorSubclassT new ArrayBlockingQueue(10)); try (PoolCleaner cleaner = cleaner(e)) { try { - e.invokeAny(null, MEDIUM_DELAY_MS, MILLISECONDS); + e.invokeAny(null, randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (NullPointerException success) {} } @@ -1671,24 +1604,25 @@ public class ThreadPoolExecutorSubclassT List> l = new ArrayList<>(); l.add(new StringTask()); try { - e.invokeAny(l, MEDIUM_DELAY_MS, null); + e.invokeAny(l, randomTimeout(), null); shouldThrow(); } catch (NullPointerException success) {} } } /** - * timed invokeAny(empty collection) throws IAE + * timed invokeAny(empty collection) throws IllegalArgumentException */ public void testTimedInvokeAny2() throws Exception { final ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10)); + final Collection> emptyCollection + = Collections.emptyList(); try (PoolCleaner cleaner = cleaner(e)) { try { - e.invokeAny(new ArrayList>(), - MEDIUM_DELAY_MS, MILLISECONDS); + e.invokeAny(emptyCollection, randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -1708,7 +1642,7 @@ public class ThreadPoolExecutorSubclassT l.add(latchAwaitingStringTask(latch)); l.add(null); try { - e.invokeAny(l, MEDIUM_DELAY_MS, MILLISECONDS); + e.invokeAny(l, randomTimeout(), MILLISECONDS); shouldThrow(); } catch (NullPointerException success) {} latch.countDown(); @@ -1766,7 +1700,7 @@ public class ThreadPoolExecutorSubclassT new ArrayBlockingQueue(10)); try (PoolCleaner cleaner = cleaner(e)) { try { - e.invokeAll(null, MEDIUM_DELAY_MS, MILLISECONDS); + e.invokeAll(null, randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (NullPointerException success) {} } @@ -1784,23 +1718,25 @@ public class ThreadPoolExecutorSubclassT List> l = new ArrayList<>(); l.add(new StringTask()); try { - e.invokeAll(l, MEDIUM_DELAY_MS, null); + e.invokeAll(l, randomTimeout(), null); shouldThrow(); } catch (NullPointerException success) {} } } /** - * timed invokeAll(empty collection) returns empty collection + * timed invokeAll(empty collection) returns empty list */ public void testTimedInvokeAll2() throws Exception { final ExecutorService e = new CustomTPE(2, 2, LONG_DELAY_MS, MILLISECONDS, new ArrayBlockingQueue(10)); + final Collection> emptyCollection + = Collections.emptyList(); try (PoolCleaner cleaner = cleaner(e)) { - List> r = e.invokeAll(new ArrayList>(), - MEDIUM_DELAY_MS, MILLISECONDS); + List> r = + e.invokeAll(emptyCollection, randomTimeout(), randomTimeUnit()); assertTrue(r.isEmpty()); } } @@ -1818,7 +1754,7 @@ public class ThreadPoolExecutorSubclassT l.add(new StringTask()); l.add(null); try { - e.invokeAll(l, MEDIUM_DELAY_MS, MILLISECONDS); + e.invokeAll(l, randomTimeout(), randomTimeUnit()); shouldThrow(); } catch (NullPointerException success) {} } @@ -1926,7 +1862,7 @@ public class ThreadPoolExecutorSubclassT public void realRun() { done.countDown(); }}); - assertTrue(done.await(LONG_DELAY_MS, MILLISECONDS)); + await(done); } }