8139237: java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java fails intermittently
authordl
Mon, 12 Sep 2016 13:11:38 -0700
changeset 40816 9756dfcba32e
parent 40815 196b358234d8
child 40817 4f5fb115676d
8139237: java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java fails intermittently Reviewed-by: martin, psandoz, shade
jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java
--- a/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java	Mon Sep 12 13:07:30 2016 -0700
+++ b/jdk/test/java/util/concurrent/ThreadPoolExecutor/ConfigChanges.java	Mon Sep 12 13:11:38 2016 -0700
@@ -28,13 +28,13 @@
  * @library /lib/testlibrary/
  * @build jdk.testlibrary.RandomFactory
  * @run main/othervm ConfigChanges
- * @key randomness intermittent
+ * @key randomness
  * @author Martin Buchholz
  */
 
 import static java.util.concurrent.TimeUnit.MILLISECONDS;
 import static java.util.concurrent.TimeUnit.MINUTES;
-import static java.util.concurrent.TimeUnit.SECONDS;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
 
 import java.security.Permission;
 import java.util.Random;
@@ -44,7 +44,6 @@
 import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.atomic.AtomicInteger;
 import jdk.testlibrary.RandomFactory;
 
 public class ConfigChanges {
@@ -95,10 +94,10 @@
             check(tpe.getQueue().isEmpty());
             check(tpe.isTerminated());
             check(! tpe.isTerminating());
-            equal(tpe.getActiveCount(), 0);
-            equal(tpe.getPoolSize(), 0);
+            equal(0, tpe.getActiveCount());
+            equal(0, tpe.getPoolSize());
             equal(tpe.getTaskCount(), tpe.getCompletedTaskCount());
-            check(tpe.awaitTermination(0L, SECONDS));
+            check(tpe.awaitTermination(0L, MINUTES));
         } catch (Throwable t) { unexpected(t); }
     }
 
@@ -110,6 +109,21 @@
 
     static volatile Runnable runnableDuJour;
 
+    static void awaitIdleness(ThreadPoolExecutor tpe, long taskCount) {
+        restart: for (;;) {
+            // check twice to make chance of race vanishingly small
+            for (int i = 0; i < 2; i++) {
+                if (tpe.getQueue().size() != 0 ||
+                    tpe.getActiveCount() != 0 ||
+                    tpe.getCompletedTaskCount() != taskCount) {
+                    Thread.yield();
+                    continue restart;
+                }
+            }
+            return;
+        }
+    }
+
     private static void realMain(String[] args) throws Throwable {
         if (rnd.nextBoolean())
             System.setSecurityManager(new PermissiveSecurityManger());
@@ -137,8 +151,9 @@
 
         if (prestart) {
             tpe.prestartAllCoreThreads();
-            equal(tg.activeCount(), n);
-            equal(tg.activeCount(), tpe.getCorePoolSize());
+            equal(n, tg.activeCount());
+            equal(n, tpe.getCorePoolSize());
+            equal(n, tpe.getLargestPoolSize());
         }
 
         final Runnable runRunnableDuJour =
@@ -153,7 +168,7 @@
                 tpe.execute(runRunnableDuJour);
             // Wait for prestarted threads to dequeue their initial tasks.
             while (! tpe.getQueue().isEmpty())
-                Thread.sleep(10);
+                Thread.sleep(1);
             for (int i = 0; i < 5*n; i++)
                 tpe.execute(runRunnableDuJour);
         } else {
@@ -163,73 +178,76 @@
 
         //report("submitted", tpe);
         pumpedUp.await();
-        equal(tg.activeCount(), 3*n);
-        equal(tg.activeCount(), tpe.getMaximumPoolSize());
-        equal(tpe.getCorePoolSize(), n);
+        equal(3*n, tg.activeCount());
+        equal(3*n, tpe.getMaximumPoolSize());
+        equal(3*n, tpe.getLargestPoolSize());
+        equal(n, tpe.getCorePoolSize());
+        equal(3*n, tpe.getActiveCount());
+        equal(6L*n, tpe.getTaskCount());
+        equal(0L, tpe.getCompletedTaskCount());
+
         //report("pumped up", tpe);
-        equal(tpe.getMaximumPoolSize(), 3*n);
         tpe.setMaximumPoolSize(4*n);
-        equal(tpe.getMaximumPoolSize(), 4*n);
+        equal(4*n, tpe.getMaximumPoolSize());
         //report("pumped up2", tpe);
         final CyclicBarrier pumpedUp2 = new CyclicBarrier(n + 1);
         runnableDuJour = waiter(pumpedUp2);
         for (int i = 0; i < 1*n; i++)
             tpe.execute(runRunnableDuJour);
         pumpedUp2.await();
-        equal(tg.activeCount(), 4*n);
-        equal(tg.activeCount(), tpe.getMaximumPoolSize());
-        equal(tpe.getCompletedTaskCount(), 0L);
+        equal(4*n, tg.activeCount());
+        equal(4*n, tpe.getMaximumPoolSize());
+        equal(4*n, tpe.getLargestPoolSize());
+        equal(4*n, tpe.getActiveCount());
+        equal(7L*n, tpe.getTaskCount());
+        equal(0L, tpe.getCompletedTaskCount());
         //report("pumped up2", tpe);
         runnableDuJour = new Runnable() { public void run() {}};
 
         tpe.setMaximumPoolSize(2*n);
-        //report("after set", tpe);
+        //report("after setMaximumPoolSize", tpe);
 
         pumpedUp2.await();
         pumpedUp.await();
 
-//      while (tg.activeCount() != n &&
-//             tg.activeCount() != n)
-//          Thread.sleep(10);
-//      equal(tg.activeCount(), n);
-//      equal(tg.activeCount(), tpe.getCorePoolSize());
-
         while (tg.activeCount() != 2*n &&
                tg.activeCount() != 2*n)
-            Thread.sleep(10);
-        equal(tg.activeCount(), 2*n);
-        equal(tg.activeCount(), tpe.getMaximumPoolSize());
-
+            Thread.yield();
+        equal(2*n, tg.activeCount());
+        equal(2*n, tpe.getMaximumPoolSize());
+        equal(4*n, tpe.getLargestPoolSize());
 
-//report("draining", tpe);
-        while (tpe.getCompletedTaskCount() < 7*n &&
-               tpe.getCompletedTaskCount() < 7*n)
-            Thread.sleep(10);
+        //report("draining", tpe);
+        awaitIdleness(tpe, 7L*n);
 
-        //equal(tg.activeCount(), n);
-        //equal(tg.activeCount(), tpe.getCorePoolSize());
-        equal(tg.activeCount(), 2*n);
-        equal(tg.activeCount(), tpe.getMaximumPoolSize());
+        equal(2*n, tg.activeCount());
+        equal(2*n, tpe.getMaximumPoolSize());
+        equal(4*n, tpe.getLargestPoolSize());
 
-        equal(tpe.getTaskCount(), 7L*n);
-        equal(tpe.getCompletedTaskCount(), 7L*n);
+        equal(7L*n, tpe.getTaskCount());
+        equal(7L*n, tpe.getCompletedTaskCount());
+        equal(0, tpe.getActiveCount());
 
-        equal(tpe.getKeepAliveTime(MINUTES), 3L);
+        equal(3L, tpe.getKeepAliveTime(MINUTES));
+        long t0 = System.nanoTime();
         tpe.setKeepAliveTime(7L, MILLISECONDS);
-        equal(tpe.getKeepAliveTime(MILLISECONDS), 7L);
+        equal(7L, tpe.getKeepAliveTime(MILLISECONDS));
         while (tg.activeCount() > n &&
                tg.activeCount() > n)
-            Thread.sleep(10);
-        equal(tg.activeCount(), n);
+            Thread.sleep(4);
+        equal(n, tg.activeCount());
+        check(System.nanoTime() - t0 >= tpe.getKeepAliveTime(NANOSECONDS));
 
         //report("idle", tpe);
         check(! tpe.allowsCoreThreadTimeOut());
+        t0 = System.nanoTime();
         tpe.allowCoreThreadTimeOut(true);
         check(tpe.allowsCoreThreadTimeOut());
         while (tg.activeCount() > 0 &&
                tg.activeCount() > 0)
-            Thread.sleep(10);
+            Thread.sleep(4);
         equal(tg.activeCount(), 0);
+        check(System.nanoTime() - t0 >= tpe.getKeepAliveTime(NANOSECONDS));
 
         //report("idle", tpe);