changeset 52887:345266000aba

8211283: Miscellaneous changes imported from jsr166 CVS 2018-11 Reviewed-by: martin, chegar
author dl
date Wed, 28 Nov 2018 15:25:14 -0800
parents 0775f246731b
children 157c1130b46e
files src/java.base/share/classes/java/util/ArrayDeque.java src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java src/java.base/share/classes/java/util/concurrent/Exchanger.java src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java test/jdk/java/util/concurrent/atomic/LongAdderDemo.java test/jdk/java/util/concurrent/tck/CompletableFutureTest.java test/jdk/java/util/concurrent/tck/ConcurrentHashMapTest.java test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java test/jdk/java/util/concurrent/tck/JSR166TestCase.java test/jdk/java/util/concurrent/tck/RecursiveTaskTest.java test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java
diffstat 14 files changed, 218 insertions(+), 213 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/util/ArrayDeque.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/src/java.base/share/classes/java/util/ArrayDeque.java	Wed Nov 28 15:25:14 2018 -0800
@@ -37,7 +37,6 @@
 import java.io.Serializable;
 import java.util.function.Consumer;
 import java.util.function.Predicate;
-
 import jdk.internal.access.SharedSecrets;
 
 /**
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java	Wed Nov 28 15:25:14 2018 -0800
@@ -2542,6 +2542,8 @@
                             setTabAt(tab, i, fwd);
                             advance = true;
                         }
+                        else if (f instanceof ReservationNode)
+                            throw new IllegalStateException("Recursive update");
                     }
                 }
             }
--- a/src/java.base/share/classes/java/util/concurrent/Exchanger.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/Exchanger.java	Wed Nov 28 15:25:14 2018 -0800
@@ -564,8 +564,8 @@
         Object item = (x == null) ? NULL_ITEM : x; // translate null args
         if (((a = arena) != null ||
              (v = slotExchange(item, false, 0L)) == null) &&
-            ((Thread.interrupted() || // disambiguates null return
-              (v = arenaExchange(item, false, 0L)) == null)))
+            (Thread.interrupted() || // disambiguates null return
+             (v = arenaExchange(item, false, 0L)) == null))
             throw new InterruptedException();
         return (v == NULL_ITEM) ? null : (V)v;
     }
@@ -620,8 +620,8 @@
         long ns = unit.toNanos(timeout);
         if ((arena != null ||
              (v = slotExchange(item, true, ns)) == null) &&
-            ((Thread.interrupted() ||
-              (v = arenaExchange(item, true, ns)) == null)))
+            (Thread.interrupted() ||
+             (v = arenaExchange(item, true, ns)) == null))
             throw new InterruptedException();
         if (v == TIMED_OUT)
             throw new TimeoutException();
--- a/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinTask.java	Wed Nov 28 15:25:14 2018 -0800
@@ -1230,14 +1230,13 @@
     /**
      * Immediately performs the base action of this task and returns
      * true if, upon return from this method, this task is guaranteed
-     * to have completed normally. This method may return false
-     * otherwise, to indicate that this task is not necessarily
-     * complete (or is not known to be complete), for example in
-     * asynchronous actions that require explicit invocations of
-     * completion methods. This method may also throw an (unchecked)
-     * exception to indicate abnormal exit. This method is designed to
-     * support extensions, and should not in general be called
-     * otherwise.
+     * to have completed. This method may return false otherwise, to
+     * indicate that this task is not necessarily complete (or is not
+     * known to be complete), for example in asynchronous actions that
+     * require explicit invocations of completion methods. This method
+     * may also throw an (unchecked) exception to indicate abnormal
+     * exit. This method is designed to support extensions, and should
+     * not in general be called otherwise.
      *
      * @return {@code true} if this task is known to have completed normally
      */
--- a/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/locks/LockSupport.java	Wed Nov 28 15:25:14 2018 -0800
@@ -199,10 +199,11 @@
      * Disables the current thread for thread scheduling purposes, for up to
      * the specified waiting time, unless the permit is available.
      *
-     * <p>If the permit is available then it is consumed and the call
-     * returns immediately; otherwise the current thread becomes disabled
-     * for thread scheduling purposes and lies dormant until one of four
-     * things happens:
+     * <p>If the specified waiting time is zero or negative, the
+     * method does nothing. Otherwise, if the permit is available then
+     * it is consumed and the call returns immediately; otherwise the
+     * current thread becomes disabled for thread scheduling purposes
+     * and lies dormant until one of four things happens:
      *
      * <ul>
      * <li>Some other thread invokes {@link #unpark unpark} with the
@@ -327,10 +328,11 @@
      * Disables the current thread for thread scheduling purposes, for up to
      * the specified waiting time, unless the permit is available.
      *
-     * <p>If the permit is available then it is consumed and the call
-     * returns immediately; otherwise the current thread becomes disabled
-     * for thread scheduling purposes and lies dormant until one of four
-     * things happens:
+     * <p>If the specified waiting time is zero or negative, the
+     * method does nothing. Otherwise, if the permit is available then
+     * it is consumed and the call returns immediately; otherwise the
+     * current thread becomes disabled for thread scheduling purposes
+     * and lies dormant until one of four things happens:
      *
      * <ul>
      * <li>Some other thread invokes {@link #unpark unpark} with the
--- a/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java	Wed Nov 28 15:25:14 2018 -0800
@@ -65,22 +65,23 @@
  *   and timed versions of {@code tryReadLock} are also provided.
  *
  *  <li><b>Optimistic Reading.</b> Method {@link #tryOptimisticRead}
- *   returns a non-zero stamp only if the lock is not currently held
- *   in write mode. Method {@link #validate} returns true if the lock
- *   has not been acquired in write mode since obtaining a given
- *   stamp.  This mode can be thought of as an extremely weak version
- *   of a read-lock, that can be broken by a writer at any time.  The
- *   use of optimistic mode for short read-only code segments often
- *   reduces contention and improves throughput.  However, its use is
- *   inherently fragile.  Optimistic read sections should only read
- *   fields and hold them in local variables for later use after
- *   validation. Fields read while in optimistic mode may be wildly
- *   inconsistent, so usage applies only when you are familiar enough
- *   with data representations to check consistency and/or repeatedly
- *   invoke method {@code validate()}.  For example, such steps are
- *   typically required when first reading an object or array
- *   reference, and then accessing one of its fields, elements or
- *   methods.
+ *   returns a non-zero stamp only if the lock is not currently held in
+ *   write mode.  Method {@link #validate} returns true if the lock has not
+ *   been acquired in write mode since obtaining a given stamp, in which
+ *   case all actions prior to the most recent write lock release
+ *   happen-before actions following the call to {@code tryOptimisticRead}.
+ *   This mode can be thought of as an extremely weak version of a
+ *   read-lock, that can be broken by a writer at any time.  The use of
+ *   optimistic read mode for short read-only code segments often reduces
+ *   contention and improves throughput.  However, its use is inherently
+ *   fragile.  Optimistic read sections should only read fields and hold
+ *   them in local variables for later use after validation. Fields read
+ *   while in optimistic read mode may be wildly inconsistent, so usage
+ *   applies only when you are familiar enough with data representations to
+ *   check consistency and/or repeatedly invoke method {@code validate()}.
+ *   For example, such steps are typically required when first reading an
+ *   object or array reference, and then accessing one of its fields,
+ *   elements or methods.
  *
  * </ul>
  *
@@ -88,8 +89,8 @@
  * conversions across the three modes. For example, method {@link
  * #tryConvertToWriteLock} attempts to "upgrade" a mode, returning
  * a valid write stamp if (1) already in writing mode (2) in reading
- * mode and there are no other readers or (3) in optimistic mode and
- * the lock is available. The forms of these methods are designed to
+ * mode and there are no other readers or (3) in optimistic read mode
+ * and the lock is available. The forms of these methods are designed to
  * help reduce some of the code bloat that otherwise occurs in
  * retry-based designs.
  *
@@ -129,6 +130,19 @@
  * #asReadWriteLock()} in applications requiring only the associated
  * set of functionality.
  *
+ * <p><b>Memory Synchronization.</b> Methods with the effect of
+ * successfully locking in any mode have the same memory
+ * synchronization effects as a <em>Lock</em> action described in
+ * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4">
+ * Chapter 17 of <cite>The Java&trade; Language Specification</cite></a>.
+ * Methods successfully unlocking in write mode have the same memory
+ * synchronization effects as an <em>Unlock</em> action.  In optimistic
+ * read usages, actions prior to the most recent write mode unlock action
+ * are guaranteed to happen-before those following a tryOptimisticRead
+ * only if a later validate returns true; otherwise there is no guarantee
+ * that the reads between tryOptimisticRead and validate obtain a
+ * consistent snapshot.
+ *
  * <p><b>Sample Usage.</b> The following illustrates some usage idioms
  * in a class that maintains simple two-dimensional points. The sample
  * code illustrates some try/catch conventions even though they are
--- a/test/jdk/java/util/concurrent/atomic/LongAdderDemo.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/test/jdk/java/util/concurrent/atomic/LongAdderDemo.java	Wed Nov 28 15:25:14 2018 -0800
@@ -93,14 +93,14 @@
         report(nthreads, incs, timeTasks(phaser), a.sum());
     }
 
-    static void report(int nthreads, int incs, long time, long sum) {
+    static void report(int nthreads, int incs, long elapsedNanos, long sum) {
         long total = (long)nthreads * incs;
         if (sum != total)
             throw new Error(sum + " != " + total);
-        double secs = (double)time / (1000L * 1000 * 1000);
-        long rate = total * (1000L) / time;
+        double elapsedSecs = (double)elapsedNanos / (1000L * 1000 * 1000);
+        long rate = total * 1000L / elapsedNanos;
         System.out.printf("threads:%3d  Time: %7.3fsec  Incs per microsec: %4d\n",
-                          nthreads, secs, rate);
+                          nthreads, elapsedSecs, rate);
     }
 
     static long timeTasks(Phaser phaser) {
--- a/test/jdk/java/util/concurrent/tck/CompletableFutureTest.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/test/jdk/java/util/concurrent/tck/CompletableFutureTest.java	Wed Nov 28 15:25:14 2018 -0800
@@ -953,17 +953,19 @@
         for (boolean createIncomplete : new boolean[] { true, false })
         for (Integer v1 : new Integer[] { 1, null })
     {
+        final AtomicInteger ran = new AtomicInteger(0);
         final CompletableFuture<Integer> f = new CompletableFuture<>();
         if (!createIncomplete) assertTrue(f.complete(v1));
         final CompletableFuture<Integer> g = m.exceptionally
             (f, (Throwable t) -> {
-                threadFail("should not be called");
-                return null;            // unreached
+                ran.getAndIncrement();
+                throw new AssertionError("should not be called");
             });
         if (createIncomplete) assertTrue(f.complete(v1));
 
         checkCompletedNormally(g, v1);
         checkCompletedNormally(f, v1);
+        assertEquals(0, ran.get());
     }}
 
     /**
@@ -975,21 +977,21 @@
         for (boolean createIncomplete : new boolean[] { true, false })
         for (Integer v1 : new Integer[] { 1, null })
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex = new CFException();
         final CompletableFuture<Integer> f = new CompletableFuture<>();
         if (!createIncomplete) f.completeExceptionally(ex);
         final CompletableFuture<Integer> g = m.exceptionally
             (f, (Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertSame(t, ex);
-                a.getAndIncrement();
+                assertSame(t, ex);
+                ran.getAndIncrement();
                 return v1;
             });
         if (createIncomplete) f.completeExceptionally(ex);
 
         checkCompletedNormally(g, v1);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1000,7 +1002,7 @@
         for (ExecutionMode m : ExecutionMode.values())
         for (boolean createIncomplete : new boolean[] { true, false })
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex1 = new CFException();
         final CFException ex2 = new CFException();
         final CompletableFuture<Integer> f = new CompletableFuture<>();
@@ -1008,15 +1010,15 @@
         final CompletableFuture<Integer> g = m.exceptionally
             (f, (Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertSame(t, ex1);
-                a.getAndIncrement();
+                assertSame(t, ex1);
+                ran.getAndIncrement();
                 throw ex2;
             });
         if (createIncomplete) f.completeExceptionally(ex1);
 
         checkCompletedWithWrappedException(g, ex2);
         checkCompletedExceptionally(f, ex1);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1028,22 +1030,22 @@
         for (boolean createIncomplete : new boolean[] { true, false })
         for (Integer v1 : new Integer[] { 1, null })
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CompletableFuture<Integer> f = new CompletableFuture<>();
         if (!createIncomplete) assertTrue(f.complete(v1));
         final CompletableFuture<Integer> g = m.whenComplete
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertSame(result, v1);
-                threadAssertNull(t);
-                a.getAndIncrement();
+                assertSame(result, v1);
+                assertNull(t);
+                ran.getAndIncrement();
             });
         if (createIncomplete) assertTrue(f.complete(v1));
 
         checkCompletedNormally(g, v1);
         checkCompletedNormally(f, v1);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1054,7 +1056,7 @@
         for (ExecutionMode m : ExecutionMode.values())
         for (boolean createIncomplete : new boolean[] { true, false })
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex = new CFException();
         final CompletableFuture<Integer> f = new CompletableFuture<>();
         if (!createIncomplete) f.completeExceptionally(ex);
@@ -1062,15 +1064,15 @@
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertNull(result);
-                threadAssertSame(t, ex);
-                a.getAndIncrement();
+                assertNull(result);
+                assertSame(t, ex);
+                ran.getAndIncrement();
             });
         if (createIncomplete) f.completeExceptionally(ex);
 
         checkCompletedWithWrappedException(g, ex);
         checkCompletedExceptionally(f, ex);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1082,22 +1084,22 @@
         for (boolean mayInterruptIfRunning : new boolean[] { true, false })
         for (boolean createIncomplete : new boolean[] { true, false })
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CompletableFuture<Integer> f = new CompletableFuture<>();
         if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
         final CompletableFuture<Integer> g = m.whenComplete
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertNull(result);
-                threadAssertTrue(t instanceof CancellationException);
-                a.getAndIncrement();
+                assertNull(result);
+                assertTrue(t instanceof CancellationException);
+                ran.getAndIncrement();
             });
         if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
 
         checkCompletedWithWrappedCancellationException(g);
         checkCancelled(f);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1109,7 +1111,7 @@
         for (ExecutionMode m : ExecutionMode.values())
         for (Integer v1 : new Integer[] { 1, null })
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex = new CFException();
         final CompletableFuture<Integer> f = new CompletableFuture<>();
         if (!createIncomplete) assertTrue(f.complete(v1));
@@ -1117,16 +1119,16 @@
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertSame(result, v1);
-                threadAssertNull(t);
-                a.getAndIncrement();
+                assertSame(result, v1);
+                assertNull(t);
+                ran.getAndIncrement();
                 throw ex;
             });
         if (createIncomplete) assertTrue(f.complete(v1));
 
         checkCompletedWithWrappedException(g, ex);
         checkCompletedNormally(f, v1);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1138,7 +1140,7 @@
         for (boolean createIncomplete : new boolean[] { true, false })
         for (ExecutionMode m : ExecutionMode.values())
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex1 = new CFException();
         final CFException ex2 = new CFException();
         final CompletableFuture<Integer> f = new CompletableFuture<>();
@@ -1148,9 +1150,9 @@
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertSame(t, ex1);
-                threadAssertNull(result);
-                a.getAndIncrement();
+                assertSame(t, ex1);
+                assertNull(result);
+                ran.getAndIncrement();
                 throw ex2;
             });
         if (createIncomplete) f.completeExceptionally(ex1);
@@ -1161,7 +1163,7 @@
             assertEquals(1, ex1.getSuppressed().length);
             assertSame(ex2, ex1.getSuppressed()[0]);
         }
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1174,22 +1176,22 @@
         for (Integer v1 : new Integer[] { 1, null })
     {
         final CompletableFuture<Integer> f = new CompletableFuture<>();
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         if (!createIncomplete) assertTrue(f.complete(v1));
         final CompletableFuture<Integer> g = m.handle
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertSame(result, v1);
-                threadAssertNull(t);
-                a.getAndIncrement();
+                assertSame(result, v1);
+                assertNull(t);
+                ran.getAndIncrement();
                 return inc(v1);
             });
         if (createIncomplete) assertTrue(f.complete(v1));
 
         checkCompletedNormally(g, inc(v1));
         checkCompletedNormally(f, v1);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1202,23 +1204,23 @@
         for (Integer v1 : new Integer[] { 1, null })
     {
         final CompletableFuture<Integer> f = new CompletableFuture<>();
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex = new CFException();
         if (!createIncomplete) f.completeExceptionally(ex);
         final CompletableFuture<Integer> g = m.handle
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertNull(result);
-                threadAssertSame(t, ex);
-                a.getAndIncrement();
+                assertNull(result);
+                assertSame(t, ex);
+                ran.getAndIncrement();
                 return v1;
             });
         if (createIncomplete) f.completeExceptionally(ex);
 
         checkCompletedNormally(g, v1);
         checkCompletedExceptionally(f, ex);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1232,22 +1234,22 @@
         for (Integer v1 : new Integer[] { 1, null })
     {
         final CompletableFuture<Integer> f = new CompletableFuture<>();
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         if (!createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
         final CompletableFuture<Integer> g = m.handle
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertNull(result);
-                threadAssertTrue(t instanceof CancellationException);
-                a.getAndIncrement();
+                assertNull(result);
+                assertTrue(t instanceof CancellationException);
+                ran.getAndIncrement();
                 return v1;
             });
         if (createIncomplete) assertTrue(f.cancel(mayInterruptIfRunning));
 
         checkCompletedNormally(g, v1);
         checkCancelled(f);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1260,23 +1262,23 @@
         for (Integer v1 : new Integer[] { 1, null })
     {
         final CompletableFuture<Integer> f = new CompletableFuture<>();
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex = new CFException();
         if (!createIncomplete) assertTrue(f.complete(v1));
         final CompletableFuture<Integer> g = m.handle
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertSame(result, v1);
-                threadAssertNull(t);
-                a.getAndIncrement();
+                assertSame(result, v1);
+                assertNull(t);
+                ran.getAndIncrement();
                 throw ex;
             });
         if (createIncomplete) assertTrue(f.complete(v1));
 
         checkCompletedWithWrappedException(g, ex);
         checkCompletedNormally(f, v1);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -1288,7 +1290,7 @@
         for (boolean createIncomplete : new boolean[] { true, false })
         for (ExecutionMode m : ExecutionMode.values())
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex1 = new CFException();
         final CFException ex2 = new CFException();
         final CompletableFuture<Integer> f = new CompletableFuture<>();
@@ -1298,16 +1300,16 @@
             (f,
              (Integer result, Throwable t) -> {
                 m.checkExecutionMode();
-                threadAssertNull(result);
-                threadAssertSame(ex1, t);
-                a.getAndIncrement();
+                assertNull(result);
+                assertSame(ex1, t);
+                ran.getAndIncrement();
                 throw ex2;
             });
         if (createIncomplete) f.completeExceptionally(ex1);
 
         checkCompletedWithWrappedException(g, ex2);
         checkCompletedExceptionally(f, ex1);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -3143,30 +3145,30 @@
         case 0:
             assertTrue(f.complete(v1));
             assertTrue(g.completeExceptionally(ex));
-            h = m.thenCompose(f, (x -> g));
+            h = m.thenCompose(f, x -> g);
             break;
         case 1:
             assertTrue(f.complete(v1));
-            h = m.thenCompose(f, (x -> g));
+            h = m.thenCompose(f, x -> g);
             assertTrue(g.completeExceptionally(ex));
             break;
         case 2:
             assertTrue(g.completeExceptionally(ex));
             assertTrue(f.complete(v1));
-            h = m.thenCompose(f, (x -> g));
+            h = m.thenCompose(f, x -> g);
             break;
         case 3:
             assertTrue(g.completeExceptionally(ex));
-            h = m.thenCompose(f, (x -> g));
+            h = m.thenCompose(f, x -> g);
             assertTrue(f.complete(v1));
             break;
         case 4:
-            h = m.thenCompose(f, (x -> g));
+            h = m.thenCompose(f, x -> g);
             assertTrue(f.complete(v1));
             assertTrue(g.completeExceptionally(ex));
             break;
         case 5:
-            h = m.thenCompose(f, (x -> g));
+            h = m.thenCompose(f, x -> g);
             assertTrue(f.complete(v1));
             assertTrue(g.completeExceptionally(ex));
             break;
@@ -3258,30 +3260,30 @@
         case 0:
             assertTrue(f.completeExceptionally(ex0));
             assertTrue(g.completeExceptionally(ex));
-            h = m.exceptionallyCompose(f, (x -> g));
+            h = m.exceptionallyCompose(f, x -> g);
             break;
         case 1:
             assertTrue(f.completeExceptionally(ex0));
-            h = m.exceptionallyCompose(f, (x -> g));
+            h = m.exceptionallyCompose(f, x -> g);
             assertTrue(g.completeExceptionally(ex));
             break;
         case 2:
             assertTrue(g.completeExceptionally(ex));
             assertTrue(f.completeExceptionally(ex0));
-            h = m.exceptionallyCompose(f, (x -> g));
+            h = m.exceptionallyCompose(f, x -> g);
             break;
         case 3:
             assertTrue(g.completeExceptionally(ex));
-            h = m.exceptionallyCompose(f, (x -> g));
+            h = m.exceptionallyCompose(f, x -> g);
             assertTrue(f.completeExceptionally(ex0));
             break;
         case 4:
-            h = m.exceptionallyCompose(f, (x -> g));
+            h = m.exceptionallyCompose(f, x -> g);
             assertTrue(f.completeExceptionally(ex0));
             assertTrue(g.completeExceptionally(ex));
             break;
         case 5:
-            h = m.exceptionallyCompose(f, (x -> g));
+            h = m.exceptionallyCompose(f, x -> g);
             assertTrue(f.completeExceptionally(ex0));
             assertTrue(g.completeExceptionally(ex));
             break;
@@ -3672,12 +3674,6 @@
         final CompletableFuture<Integer> complete = CompletableFuture.completedFuture(v);
         final CompletableFuture<Integer> incomplete = new CompletableFuture<>();
 
-        List<CompletableFuture<?>> futures = new ArrayList<>();
-
-        List<CompletableFuture<Integer>> srcs = new ArrayList<>();
-        srcs.add(complete);
-        srcs.add(incomplete);
-
         List<CompletableFuture<?>> fs = new ArrayList<>();
         fs.add(incomplete.thenRunAsync(() -> {}, e));
         fs.add(incomplete.thenAcceptAsync(z -> {}, e));
@@ -4862,18 +4858,21 @@
         for (boolean createIncomplete : new boolean[] { true, false })
         for (Integer v1 : new Integer[] { 1, null })
     {
+        final AtomicInteger ran = new AtomicInteger(0);
         final CompletableFuture<Integer> f = new CompletableFuture<>();
         final DelegatedCompletionStage<Integer> d =
             new DelegatedCompletionStage<Integer>(f);
         if (!createIncomplete) assertTrue(f.complete(v1));
         final CompletionStage<Integer> g = d.exceptionallyAsync
             ((Throwable t) -> {
-                threadFail("should not be called");
-                return null;            // unreached
+                ran.getAndIncrement();
+                throw new AssertionError("should not be called");
             });
         if (createIncomplete) assertTrue(f.complete(v1));
 
         checkCompletedNormally(g.toCompletableFuture(), v1);
+        checkCompletedNormally(f, v1);
+        assertEquals(0, ran.get());
     }}
 
     /**
@@ -4884,7 +4883,7 @@
         for (boolean createIncomplete : new boolean[] { true, false })
         for (Integer v1 : new Integer[] { 1, null })
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex = new CFException();
         final CompletableFuture<Integer> f = new CompletableFuture<>();
         final DelegatedCompletionStage<Integer> d =
@@ -4892,14 +4891,15 @@
         if (!createIncomplete) f.completeExceptionally(ex);
         final CompletionStage<Integer> g = d.exceptionallyAsync
             ((Throwable t) -> {
-                threadAssertSame(t, ex);
-                a.getAndIncrement();
+                assertSame(t, ex);
+                ran.getAndIncrement();
                 return v1;
             });
         if (createIncomplete) f.completeExceptionally(ex);
 
         checkCompletedNormally(g.toCompletableFuture(), v1);
-        assertEquals(1, a.get());
+        checkCompletedExceptionally(f, ex);
+        assertEquals(1, ran.get());
     }}
 
     /**
@@ -4910,7 +4910,7 @@
     public void testDefaultExceptionallyAsync_exceptionalCompletionActionFailed() {
         for (boolean createIncomplete : new boolean[] { true, false })
     {
-        final AtomicInteger a = new AtomicInteger(0);
+        final AtomicInteger ran = new AtomicInteger(0);
         final CFException ex1 = new CFException();
         final CFException ex2 = new CFException();
         final CompletableFuture<Integer> f = new CompletableFuture<>();
@@ -4919,8 +4919,8 @@
         if (!createIncomplete) f.completeExceptionally(ex1);
         final CompletionStage<Integer> g = d.exceptionallyAsync
             ((Throwable t) -> {
-                threadAssertSame(t, ex1);
-                a.getAndIncrement();
+                assertSame(t, ex1);
+                ran.getAndIncrement();
                 throw ex2;
             });
         if (createIncomplete) f.completeExceptionally(ex1);
@@ -4928,7 +4928,7 @@
         checkCompletedWithWrappedException(g.toCompletableFuture(), ex2);
         checkCompletedExceptionally(f, ex1);
         checkCompletedExceptionally(d.toCompletableFuture(), ex1);
-        assertEquals(1, a.get());
+        assertEquals(1, ran.get());
     }}
 
     /**
--- a/test/jdk/java/util/concurrent/tck/ConcurrentHashMapTest.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/test/jdk/java/util/concurrent/tck/ConcurrentHashMapTest.java	Wed Nov 28 15:25:14 2018 -0800
@@ -865,4 +865,20 @@
         assertEquals(mapSize, map.size());
     }
 
+    public void testReentrantComputeIfAbsent() {
+        ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>(16);
+        try {
+            for (int i = 0; i < 100; i++) { // force a resize
+                map.computeIfAbsent(i, key -> findValue(map, key));
+            }
+            fail("recursive computeIfAbsent should throw IllegalStateException");
+        } catch (IllegalStateException success) {}
+    }
+
+    private Integer findValue(ConcurrentHashMap<Integer, Integer> map,
+                              Integer key) {
+        return (key % 5 == 0) ?  key :
+            map.computeIfAbsent(key + 1, k -> findValue(map, k));
+    }
+
 }
--- a/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java	Wed Nov 28 15:25:14 2018 -0800
@@ -136,7 +136,7 @@
                 return n;
             FibTask f1 = new FibTask(n - 1);
             f1.fork();
-            return (new FibTask(n - 2)).compute() + f1.join();
+            return new FibTask(n - 2).compute() + f1.join();
         }
     }
 
--- a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java	Wed Nov 28 15:25:14 2018 -0800
@@ -144,13 +144,21 @@
  *
  * <ol>
  *
- * <li>All assertions in code running in generated threads must use
- * the forms {@link #threadFail}, {@link #threadAssertTrue}, {@link
- * #threadAssertEquals}, or {@link #threadAssertNull}, (not
- * {@code fail}, {@code assertTrue}, etc.) It is OK (but not
- * particularly recommended) for other code to use these forms too.
- * Only the most typically used JUnit assertion methods are defined
- * this way, but enough to live with.
+ * <li>All code not running in the main test thread (manually spawned threads
+ * or the common fork join pool) must be checked for failure (and completion!).
+ * Mechanisms that can be used to ensure this are:
+ *   <ol>
+ *   <li>Signalling via a synchronizer like AtomicInteger or CountDownLatch
+ *    that the task completed normally, which is checked before returning from
+ *    the test method in the main thread.
+ *   <li>Using the forms {@link #threadFail}, {@link #threadAssertTrue},
+ *    or {@link #threadAssertNull}, (not {@code fail}, {@code assertTrue}, etc.)
+ *    Only the most typically used JUnit assertion methods are defined
+ *    this way, but enough to live with.
+ *   <li>Recording failure explicitly using {@link #threadUnexpectedException}
+ *    or {@link #threadRecordFailure}.
+ *   <li>Using a wrapper like CheckedRunnable that uses one the mechanisms above.
+ *   </ol>
  *
  * <li>If you override {@link #setUp} or {@link #tearDown}, make sure
  * to invoke {@code super.setUp} and {@code super.tearDown} within
@@ -1318,22 +1326,33 @@
     /**
      * Spin-waits up to the specified number of milliseconds for the given
      * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
+     * @param waitingForGodot if non-null, an additional condition to satisfy
      */
-    void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
-        long startTime = 0L;
-        for (;;) {
-            Thread.State s = thread.getState();
-            if (s == Thread.State.BLOCKED ||
-                s == Thread.State.WAITING ||
-                s == Thread.State.TIMED_WAITING)
-                return;
-            else if (s == Thread.State.TERMINATED)
+    void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis,
+                                       Callable<Boolean> waitingForGodot) {
+        for (long startTime = 0L;;) {
+            switch (thread.getState()) {
+            default: break;
+            case BLOCKED: case WAITING: case TIMED_WAITING:
+                try {
+                    if (waitingForGodot == null || waitingForGodot.call())
+                        return;
+                } catch (Throwable fail) { threadUnexpectedException(fail); }
+                break;
+            case TERMINATED:
                 fail("Unexpected thread termination");
-            else if (startTime == 0L)
+            }
+
+            if (startTime == 0L)
                 startTime = System.nanoTime();
             else if (millisElapsedSince(startTime) > timeoutMillis) {
-                threadAssertTrue(thread.isAlive());
-                fail("timed out waiting for thread to enter wait state");
+                assertTrue(thread.isAlive());
+                if (waitingForGodot == null
+                    || thread.getState() == Thread.State.RUNNABLE)
+                    fail("timed out waiting for thread to enter wait state");
+                else
+                    fail("timed out waiting for condition, thread state="
+                         + thread.getState());
             }
             Thread.yield();
         }
@@ -1341,32 +1360,10 @@
 
     /**
      * Spin-waits up to the specified number of milliseconds for the given
-     * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
-     * and additionally satisfy the given condition.
+     * thread to enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
      */
-    void waitForThreadToEnterWaitState(
-        Thread thread, long timeoutMillis, Callable<Boolean> waitingForGodot) {
-        long startTime = 0L;
-        for (;;) {
-            Thread.State s = thread.getState();
-            if (s == Thread.State.BLOCKED ||
-                s == Thread.State.WAITING ||
-                s == Thread.State.TIMED_WAITING) {
-                try {
-                    if (waitingForGodot.call())
-                        return;
-                } catch (Throwable fail) { threadUnexpectedException(fail); }
-            }
-            else if (s == Thread.State.TERMINATED)
-                fail("Unexpected thread termination");
-            else if (startTime == 0L)
-                startTime = System.nanoTime();
-            else if (millisElapsedSince(startTime) > timeoutMillis) {
-                threadAssertTrue(thread.isAlive());
-                fail("timed out waiting for thread to enter wait state");
-            }
-            Thread.yield();
-        }
+    void waitForThreadToEnterWaitState(Thread thread, long timeoutMillis) {
+        waitForThreadToEnterWaitState(thread, timeoutMillis, null);
     }
 
     /**
@@ -1374,7 +1371,7 @@
      * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING.
      */
     void waitForThreadToEnterWaitState(Thread thread) {
-        waitForThreadToEnterWaitState(thread, LONG_DELAY_MS);
+        waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, null);
     }
 
     /**
@@ -1382,8 +1379,8 @@
      * enter a wait state: BLOCKED, WAITING, or TIMED_WAITING,
      * and additionally satisfy the given condition.
      */
-    void waitForThreadToEnterWaitState(
-        Thread thread, Callable<Boolean> waitingForGodot) {
+    void waitForThreadToEnterWaitState(Thread thread,
+                                       Callable<Boolean> waitingForGodot) {
         waitForThreadToEnterWaitState(thread, LONG_DELAY_MS, waitingForGodot);
     }
 
@@ -1491,11 +1488,12 @@
         public final void run() {
             try {
                 realRun();
-                threadShouldThrow(exceptionClass.getSimpleName());
             } catch (Throwable t) {
                 if (! exceptionClass.isInstance(t))
                     threadUnexpectedException(t);
+                return;
             }
+            threadShouldThrow(exceptionClass.getSimpleName());
         }
     }
 
@@ -1505,12 +1503,13 @@
         public final void run() {
             try {
                 realRun();
-                threadShouldThrow("InterruptedException");
             } catch (InterruptedException success) {
                 threadAssertFalse(Thread.interrupted());
+                return;
             } catch (Throwable fail) {
                 threadUnexpectedException(fail);
             }
+            threadShouldThrow("InterruptedException");
         }
     }
 
@@ -1522,26 +1521,8 @@
                 return realCall();
             } catch (Throwable fail) {
                 threadUnexpectedException(fail);
-                return null;
             }
-        }
-    }
-
-    public abstract class CheckedInterruptedCallable<T>
-        implements Callable<T> {
-        protected abstract T realCall() throws Throwable;
-
-        public final T call() {
-            try {
-                T result = realCall();
-                threadShouldThrow("InterruptedException");
-                return result;
-            } catch (InterruptedException success) {
-                threadAssertFalse(Thread.interrupted());
-            } catch (Throwable fail) {
-                threadUnexpectedException(fail);
-            }
-            return null;
+            throw new AssertionError("unreached");
         }
     }
 
@@ -1656,14 +1637,6 @@
         public String call() { throw new NullPointerException(); }
     }
 
-    public class SmallPossiblyInterruptedRunnable extends CheckedRunnable {
-        protected void realRun() {
-            try {
-                delay(SMALL_DELAY_MS);
-            } catch (InterruptedException ok) {}
-        }
-    }
-
     public Runnable possiblyInterruptedRunnable(final long timeoutMillis) {
         return new CheckedRunnable() {
             protected void realRun() {
@@ -1719,8 +1692,8 @@
                 return realCompute();
             } catch (Throwable fail) {
                 threadUnexpectedException(fail);
-                return null;
             }
+            throw new AssertionError("unreached");
         }
     }
 
--- a/test/jdk/java/util/concurrent/tck/RecursiveTaskTest.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/test/jdk/java/util/concurrent/tck/RecursiveTaskTest.java	Wed Nov 28 15:25:14 2018 -0800
@@ -225,7 +225,7 @@
                 return n;
             FibTask f1 = new FibTask(n - 1);
             f1.fork();
-            return (new FibTask(n - 2)).compute() + f1.join();
+            return new FibTask(n - 2).compute() + f1.join();
         }
 
         public void publicSetRawResult(Integer result) {
@@ -244,7 +244,7 @@
                 throw new FJException();
             FailingFibTask f1 = new FailingFibTask(n - 1);
             f1.fork();
-            return (new FibTask(n - 2)).compute() + f1.join();
+            return new FibTask(n - 2).compute() + f1.join();
         }
     }
 
--- a/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/test/jdk/java/util/concurrent/tck/ScheduledExecutorSubclassTest.java	Wed Nov 28 15:25:14 2018 -0800
@@ -676,7 +676,7 @@
         final CustomExecutor p = new CustomExecutor(1);
         try (PoolCleaner cleaner = cleaner(p, releaser)) {
             for (int i = 0; i < tasks.length; i++)
-                tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
+                tasks[i] = p.schedule(possiblyInterruptedRunnable(SMALL_DELAY_MS),
                                       LONG_DELAY_MS, MILLISECONDS);
             int max = tasks.length;
             if (tasks[4].cancel(true)) --max;
--- a/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java	Wed Nov 28 15:25:14 2018 -0800
+++ b/test/jdk/java/util/concurrent/tck/ScheduledExecutorTest.java	Wed Nov 28 15:25:14 2018 -0800
@@ -634,7 +634,7 @@
         final ScheduledThreadPoolExecutor p = new ScheduledThreadPoolExecutor(1);
         try (PoolCleaner cleaner = cleaner(p, releaser)) {
             for (int i = 0; i < tasks.length; i++)
-                tasks[i] = p.schedule(new SmallPossiblyInterruptedRunnable(),
+                tasks[i] = p.schedule(possiblyInterruptedRunnable(SMALL_DELAY_MS),
                                       LONG_DELAY_MS, MILLISECONDS);
             int max = tasks.length;
             if (tasks[4].cancel(true)) --max;