8186056: Miscellaneous changes imported from jsr166 CVS 2017-09
authordl
Tue, 03 Oct 2017 14:00:00 -0700
changeset 47307 6864969a78ad
parent 47306 90b7465b9ac7
child 47308 5f351a1131e0
8186056: Miscellaneous changes imported from jsr166 CVS 2017-09 Reviewed-by: martin, psandoz
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/ExecutorCompletionService.java
src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java
src/java.base/share/classes/java/util/concurrent/TimeUnit.java
src/java.base/share/classes/java/util/concurrent/locks/Condition.java
test/jdk/java/util/Collection/IteratorMicroBenchmark.java
test/jdk/java/util/Collection/RemoveMicroBenchmark.java
test/jdk/java/util/Collection/testlibrary/CollectionAsserts.java
test/jdk/java/util/Collection/testlibrary/ExtendsAbstractCollection.java
test/jdk/java/util/List/ListDefaults.java
test/jdk/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java
test/jdk/java/util/concurrent/tck/Collection8Test.java
test/jdk/java/util/concurrent/tck/LinkedTransferQueueTest.java
test/jdk/java/util/concurrent/tck/StampedLockTest.java
test/jdk/java/util/concurrent/tck/ThreadLocalRandomTest.java
--- a/src/java.base/share/classes/java/util/ArrayDeque.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/src/java.base/share/classes/java/util/ArrayDeque.java	Tue Oct 03 14:00:00 2017 -0700
@@ -211,7 +211,7 @@
     }
 
     /**
-     * Increments i, mod modulus.
+     * Circularly increments i, mod modulus.
      * Precondition and postcondition: 0 <= i < modulus.
      */
     static final int inc(int i, int modulus) {
@@ -220,7 +220,7 @@
     }
 
     /**
-     * Decrements i, mod modulus.
+     * Circularly decrements i, mod modulus.
      * Precondition and postcondition: 0 <= i < modulus.
      */
     static final int dec(int i, int modulus) {
@@ -233,7 +233,7 @@
      * Precondition: 0 <= i < modulus, 0 <= distance <= modulus.
      * @return index 0 <= i < modulus
      */
-    static final int add(int i, int distance, int modulus) {
+    static final int inc(int i, int distance, int modulus) {
         if ((i += distance) - modulus >= 0) i -= modulus;
         return i;
     }
@@ -825,7 +825,7 @@
             final int i, n;
             return ((n = sub(getFence(), i = cursor, es.length) >> 1) <= 0)
                 ? null
-                : new DeqSpliterator(i, cursor = add(i, n, es.length));
+                : new DeqSpliterator(i, cursor = inc(i, n, es.length));
         }
 
         public void forEachRemaining(Consumer<? super E> action) {
--- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java	Tue Oct 03 14:00:00 2017 -0700
@@ -1394,8 +1394,8 @@
     }
 
     /**
-     * Saves the state of the {@code ConcurrentHashMap} instance to a
-     * stream (i.e., serializes it).
+     * Saves this map to a stream (that is, serializes it).
+     *
      * @param s the stream
      * @throws java.io.IOException if an I/O error occurs
      * @serialData
@@ -1439,7 +1439,7 @@
     }
 
     /**
-     * Reconstitutes the instance from a stream (that is, deserializes it).
+     * Reconstitutes this map from a stream (that is, deserializes it).
      * @param s the stream
      * @throws ClassNotFoundException if the class of a serialized object
      *         could not be found
--- a/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/src/java.base/share/classes/java/util/concurrent/ExecutorCompletionService.java	Tue Oct 03 14:00:00 2017 -0700
@@ -174,6 +174,10 @@
         this.completionQueue = completionQueue;
     }
 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
     public Future<V> submit(Callable<V> task) {
         if (task == null) throw new NullPointerException();
         RunnableFuture<V> f = newTaskFor(task);
@@ -181,6 +185,10 @@
         return f;
     }
 
+    /**
+     * @throws RejectedExecutionException {@inheritDoc}
+     * @throws NullPointerException       {@inheritDoc}
+     */
     public Future<V> submit(Runnable task, V result) {
         if (task == null) throw new NullPointerException();
         RunnableFuture<V> f = newTaskFor(task, result);
--- a/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java	Tue Oct 03 14:00:00 2017 -0700
@@ -383,7 +383,7 @@
      */
     private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
     private static final int COUNT_BITS = Integer.SIZE - 3;
-    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;
+    private static final int COUNT_MASK = (1 << COUNT_BITS) - 1;
 
     // runState is stored in the high-order bits
     private static final int RUNNING    = -1 << COUNT_BITS;
@@ -393,8 +393,8 @@
     private static final int TERMINATED =  3 << COUNT_BITS;
 
     // Packing and unpacking ctl
-    private static int runStateOf(int c)     { return c & ~CAPACITY; }
-    private static int workerCountOf(int c)  { return c & CAPACITY; }
+    private static int runStateOf(int c)     { return c & ~COUNT_MASK; }
+    private static int workerCountOf(int c)  { return c & COUNT_MASK; }
     private static int ctlOf(int rs, int wc) { return rs | wc; }
 
     /*
@@ -434,7 +434,7 @@
      * decrements are performed within getTask.
      */
     private void decrementWorkerCount() {
-        do {} while (! compareAndDecrementWorkerCount(ctl.get()));
+        ctl.addAndGet(-1);
     }
 
     /**
@@ -538,12 +538,17 @@
      * Core pool size is the minimum number of workers to keep alive
      * (and not allow to time out etc) unless allowCoreThreadTimeOut
      * is set, in which case the minimum is zero.
+     *
+     * Since the worker count is actually stored in COUNT_BITS bits,
+     * the effective limit is {@code corePoolSize & COUNT_MASK}.
      */
     private volatile int corePoolSize;
 
     /**
-     * Maximum pool size. Note that the actual maximum is internally
-     * bounded by CAPACITY.
+     * Maximum pool size.
+     *
+     * Since the worker count is actually stored in COUNT_BITS bits,
+     * the effective limit is {@code maximumPoolSize & COUNT_MASK}.
      */
     private volatile int maximumPoolSize;
 
@@ -705,7 +710,7 @@
             int c = ctl.get();
             if (isRunning(c) ||
                 runStateAtLeast(c, TIDYING) ||
-                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
+                (runStateLessThan(c, STOP) && ! workQueue.isEmpty()))
                 return;
             if (workerCountOf(c) != 0) { // Eligible to terminate
                 interruptIdleWorkers(ONLY_ONE);
@@ -744,17 +749,12 @@
      * specially.
      */
     private void checkShutdownAccess() {
+        // assert mainLock.isHeldByCurrentThread();
         SecurityManager security = System.getSecurityManager();
         if (security != null) {
             security.checkPermission(shutdownPerm);
-            final ReentrantLock mainLock = this.mainLock;
-            mainLock.lock();
-            try {
-                for (Worker w : workers)
-                    security.checkAccess(w.thread);
-            } finally {
-                mainLock.unlock();
-            }
+            for (Worker w : workers)
+                security.checkAccess(w.thread);
         }
     }
 
@@ -763,14 +763,9 @@
      * (in which case some threads may remain uninterrupted).
      */
     private void interruptWorkers() {
-        final ReentrantLock mainLock = this.mainLock;
-        mainLock.lock();
-        try {
-            for (Worker w : workers)
-                w.interruptIfStarted();
-        } finally {
-            mainLock.unlock();
-        }
+        // assert mainLock.isHeldByCurrentThread();
+        for (Worker w : workers)
+            w.interruptIfStarted();
     }
 
     /**
@@ -896,26 +891,22 @@
      */
     private boolean addWorker(Runnable firstTask, boolean core) {
         retry:
-        for (;;) {
-            int c = ctl.get();
-            int rs = runStateOf(c);
-
+        for (int c = ctl.get();;) {
             // Check if queue empty only if necessary.
-            if (rs >= SHUTDOWN &&
-                ! (rs == SHUTDOWN &&
-                   firstTask == null &&
-                   ! workQueue.isEmpty()))
+            if (runStateAtLeast(c, SHUTDOWN)
+                && (runStateAtLeast(c, STOP)
+                    || firstTask != null
+                    || workQueue.isEmpty()))
                 return false;
 
             for (;;) {
-                int wc = workerCountOf(c);
-                if (wc >= CAPACITY ||
-                    wc >= (core ? corePoolSize : maximumPoolSize))
+                if (workerCountOf(c)
+                    >= ((core ? corePoolSize : maximumPoolSize) & COUNT_MASK))
                     return false;
                 if (compareAndIncrementWorkerCount(c))
                     break retry;
                 c = ctl.get();  // Re-read ctl
-                if (runStateOf(c) != rs)
+                if (runStateAtLeast(c, SHUTDOWN))
                     continue retry;
                 // else CAS failed due to workerCount change; retry inner loop
             }
@@ -934,10 +925,10 @@
                     // Recheck while holding lock.
                     // Back out on ThreadFactory failure or if
                     // shut down before lock acquired.
-                    int rs = runStateOf(ctl.get());
+                    int c = ctl.get();
 
-                    if (rs < SHUTDOWN ||
-                        (rs == SHUTDOWN && firstTask == null)) {
+                    if (isRunning(c) ||
+                        (runStateLessThan(c, STOP) && firstTask == null)) {
                         if (t.isAlive()) // precheck that t is startable
                             throw new IllegalThreadStateException();
                         workers.add(w);
@@ -1044,10 +1035,10 @@
 
         for (;;) {
             int c = ctl.get();
-            int rs = runStateOf(c);
 
             // Check if queue empty only if necessary.
-            if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
+            if (runStateAtLeast(c, SHUTDOWN)
+                && (runStateAtLeast(c, STOP) || workQueue.isEmpty())) {
                 decrementWorkerCount();
                 return null;
             }
@@ -1140,17 +1131,12 @@
                     wt.interrupt();
                 try {
                     beforeExecute(wt, task);
-                    Throwable thrown = null;
                     try {
                         task.run();
-                    } catch (RuntimeException x) {
-                        thrown = x; throw x;
-                    } catch (Error x) {
-                        thrown = x; throw x;
-                    } catch (Throwable x) {
-                        thrown = x; throw new Error(x);
-                    } finally {
-                        afterExecute(task, thrown);
+                        afterExecute(task, null);
+                    } catch (Throwable ex) {
+                        afterExecute(task, ex);
+                        throw ex;
                     }
                 } finally {
                     task = null;
@@ -1331,7 +1317,7 @@
      *
      * If the task cannot be submitted for execution, either because this
      * executor has been shutdown or because its capacity has been reached,
-     * the task is handled by the current {@code RejectedExecutionHandler}.
+     * the task is handled by the current {@link RejectedExecutionHandler}.
      *
      * @param command the task to execute
      * @throws RejectedExecutionException at discretion of
@@ -1438,7 +1424,7 @@
     }
 
     public boolean isShutdown() {
-        return ! isRunning(ctl.get());
+        return runStateAtLeast(ctl.get(), SHUTDOWN);
     }
 
     /** Used by ScheduledThreadPoolExecutor. */
@@ -1459,7 +1445,7 @@
      */
     public boolean isTerminating() {
         int c = ctl.get();
-        return ! isRunning(c) && runStateLessThan(c, TERMINATED);
+        return runStateAtLeast(c, SHUTDOWN) && runStateLessThan(c, TERMINATED);
     }
 
     public boolean isTerminated() {
@@ -1472,7 +1458,7 @@
         final ReentrantLock mainLock = this.mainLock;
         mainLock.lock();
         try {
-            while (!runStateAtLeast(ctl.get(), TERMINATED)) {
+            while (runStateLessThan(ctl.get(), TERMINATED)) {
                 if (nanos <= 0L)
                     return false;
                 nanos = termination.awaitNanos(nanos);
@@ -1951,7 +1937,7 @@
         }
         int c = ctl.get();
         String runState =
-            runStateLessThan(c, SHUTDOWN) ? "Running" :
+            isRunning(c) ? "Running" :
             runStateAtLeast(c, TERMINATED) ? "Terminated" :
             "Shutting down";
         return super.toString() +
--- a/src/java.base/share/classes/java/util/concurrent/TimeUnit.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/src/java.base/share/classes/java/util/concurrent/TimeUnit.java	Tue Oct 03 14:00:00 2017 -0700
@@ -342,11 +342,13 @@
      * using:
      *
      * <pre> {@code
-     * public synchronized Object poll(long timeout, TimeUnit unit)
+     * public E poll(long timeout, TimeUnit unit)
      *     throws InterruptedException {
-     *   while (empty) {
-     *     unit.timedWait(this, timeout);
-     *     ...
+     *   synchronized (lock) {
+     *     while (isEmpty()) {
+     *       unit.timedWait(lock, timeout);
+     *       ...
+     *     }
      *   }
      * }}</pre>
      *
--- a/src/java.base/share/classes/java/util/concurrent/locks/Condition.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/src/java.base/share/classes/java/util/concurrent/locks/Condition.java	Tue Oct 03 14:00:00 2017 -0700
@@ -73,7 +73,7 @@
  * available in the buffer. This can be achieved using two
  * {@link Condition} instances.
  * <pre>
- * class BoundedBuffer {
+ * class BoundedBuffer&lt;E&gt; {
  *   <b>final Lock lock = new ReentrantLock();</b>
  *   final Condition notFull  = <b>lock.newCondition(); </b>
  *   final Condition notEmpty = <b>lock.newCondition(); </b>
@@ -81,7 +81,7 @@
  *   final Object[] items = new Object[100];
  *   int putptr, takeptr, count;
  *
- *   public void put(Object x) throws InterruptedException {
+ *   public void put(E x) throws InterruptedException {
  *     <b>lock.lock();
  *     try {</b>
  *       while (count == items.length)
@@ -95,12 +95,12 @@
  *     }</b>
  *   }
  *
- *   public Object take() throws InterruptedException {
+ *   public E take() throws InterruptedException {
  *     <b>lock.lock();
  *     try {</b>
  *       while (count == 0)
  *         <b>notEmpty.await();</b>
- *       Object x = items[takeptr];
+ *       E x = (E) items[takeptr];
  *       if (++takeptr == items.length) takeptr = 0;
  *       --count;
  *       <b>notFull.signal();</b>
@@ -310,7 +310,8 @@
      * the following form:
      *
      * <pre> {@code
-     * boolean aMethod(long timeout, TimeUnit unit) {
+     * boolean aMethod(long timeout, TimeUnit unit)
+     *     throws InterruptedException {
      *   long nanos = unit.toNanos(timeout);
      *   lock.lock();
      *   try {
@@ -320,6 +321,7 @@
      *       nanos = theCondition.awaitNanos(nanos);
      *     }
      *     // ...
+     *     return true;
      *   } finally {
      *     lock.unlock();
      *   }
@@ -410,7 +412,8 @@
      * <p>The return value indicates whether the deadline has elapsed,
      * which can be used as follows:
      * <pre> {@code
-     * boolean aMethod(Date deadline) {
+     * boolean aMethod(Date deadline)
+     *     throws InterruptedException {
      *   boolean stillWaiting = true;
      *   lock.lock();
      *   try {
@@ -420,6 +423,7 @@
      *       stillWaiting = theCondition.awaitUntil(deadline);
      *     }
      *     // ...
+     *     return true;
      *   } finally {
      *     lock.unlock();
      *   }
--- a/test/jdk/java/util/Collection/IteratorMicroBenchmark.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/Collection/IteratorMicroBenchmark.java	Tue Oct 03 14:00:00 2017 -0700
@@ -36,12 +36,10 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Deque;
-import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Map;
 import java.util.PriorityQueue;
 import java.util.Spliterator;
 import java.util.Vector;
@@ -52,7 +50,6 @@
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.LinkedTransferQueue;
 import java.util.concurrent.PriorityBlockingQueue;
-import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
--- a/test/jdk/java/util/Collection/RemoveMicroBenchmark.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/Collection/RemoveMicroBenchmark.java	Tue Oct 03 14:00:00 2017 -0700
@@ -29,20 +29,16 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayDeque;
-import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Deque;
-import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
-import java.util.Map;
 import java.util.PriorityQueue;
 import java.util.Queue;
-import java.util.Spliterator;
 import java.util.Vector;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingDeque;
--- a/test/jdk/java/util/Collection/testlibrary/CollectionAsserts.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/Collection/testlibrary/CollectionAsserts.java	Tue Oct 03 14:00:00 2017 -0700
@@ -23,7 +23,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.Iterator;
--- a/test/jdk/java/util/Collection/testlibrary/ExtendsAbstractCollection.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/Collection/testlibrary/ExtendsAbstractCollection.java	Tue Oct 03 14:00:00 2017 -0700
@@ -21,8 +21,6 @@
  * questions.
  */
 import java.util.AbstractCollection;
-import java.util.HashSet;
-import java.util.AbstractSet;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
--- a/test/jdk/java/util/List/ListDefaults.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/List/ListDefaults.java	Tue Oct 03 14:00:00 2017 -0700
@@ -42,12 +42,10 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
-import java.lang.reflect.Constructor;
 import java.util.ConcurrentModificationException;
 import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
-import java.util.function.Supplier;
 
 /**
  * @test
--- a/test/jdk/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/concurrent/ThreadPoolExecutor/ThrowingTasks.java	Tue Oct 03 14:00:00 2017 -0700
@@ -43,7 +43,6 @@
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.Supplier;
 
@@ -55,26 +54,18 @@
         extends ConcurrentHashMap<Class<?>, Integer> {
 
         void inc(Class<?> key) {
-            for (;;) {
-                Integer i = get(key);
-                if (i == null) {
-                    if (putIfAbsent(key, 1) == null)
-                        return;
-                } else {
-                    if (replace(key, i, i + 1))
-                        return;
-                }
-            }
+            compute(key, (k, v) -> (v == null) ? 1 : v + 1);
         }
     }
 
+    /** Double-check that HashTable and ConcurrentHashMap are work-alikes. */
     @SuppressWarnings("serial")
     static class UncaughtExceptionsTable
         extends Hashtable<Class<?>, Integer> {
 
         synchronized void inc(Class<?> key) {
-            Integer i = get(key);
-            put(key, (i == null) ? 1 : i + 1);
+            Integer v = get(key);
+            put(key, (v == null) ? 1 : v + 1);
         }
     }
 
@@ -82,37 +73,20 @@
         = new UncaughtExceptions();
     static final UncaughtExceptionsTable uncaughtExceptionsTable
         = new UncaughtExceptionsTable();
-    static final AtomicLong totalUncaughtExceptions
-        = new AtomicLong(0);
+    static final AtomicInteger totalUncaughtExceptions
+        = new AtomicInteger(0);
     static final CountDownLatch uncaughtExceptionsLatch
         = new CountDownLatch(24);
 
-    static final Thread.UncaughtExceptionHandler handler
-        = new Thread.UncaughtExceptionHandler() {
-                public void uncaughtException(Thread t, Throwable e) {
-                    check(! Thread.currentThread().isInterrupted());
-                    totalUncaughtExceptions.getAndIncrement();
-                    uncaughtExceptions.inc(e.getClass());
-                    uncaughtExceptionsTable.inc(e.getClass());
-                    uncaughtExceptionsLatch.countDown();
-                }};
-
     static final ThreadGroup tg = new ThreadGroup("Flaky");
 
-    static final ThreadFactory tf = new ThreadFactory() {
-            public Thread newThread(Runnable r) {
-                Thread t = new Thread(tg, r);
-                t.setUncaughtExceptionHandler(handler);
-                return t;
-            }};
-
     static final RuntimeException rte = new RuntimeException();
     static final Error error = new Error();
     static final Throwable weird = new Throwable();
     static final Exception checkedException = new Exception();
 
     static class Thrower implements Runnable {
-        Throwable t;
+        final Throwable t;
         Thrower(Throwable t) { this.t = t; }
         public void run() {
             if (t != null)
@@ -120,14 +94,12 @@
         }
     }
 
-    static final Thrower noThrower      = new Thrower(null);
-    static final Thrower rteThrower     = new Thrower(rte);
-    static final Thrower errorThrower   = new Thrower(error);
-    static final Thrower weirdThrower   = new Thrower(weird);
-    static final Thrower checkedThrower = new Thrower(checkedException);
-
     static final List<Thrower> throwers = Arrays.asList(
-        noThrower, rteThrower, errorThrower, weirdThrower, checkedThrower);
+        new Thrower(null),
+        new Thrower(rte),
+        new Thrower(error),
+        new Thrower(weird),
+        new Thrower(checkedException));
 
     static class Flaky implements Runnable {
         final Runnable beforeExecute;
@@ -190,7 +162,18 @@
             super(10, 10,
                   1L, TimeUnit.HOURS,
                   new LinkedBlockingQueue<Runnable>(),
-                  tf);
+                  (ThreadFactory) (runnable) -> {
+                      Thread thread = new Thread(tg, runnable);
+                      Thread.UncaughtExceptionHandler handler = (t, e) -> {
+                          check(! t.isInterrupted());
+                          totalUncaughtExceptions.getAndIncrement();
+                          uncaughtExceptions.inc(e.getClass());
+                          uncaughtExceptionsTable.inc(e.getClass());
+                          uncaughtExceptionsLatch.countDown();
+                      };
+                      thread.setUncaughtExceptionHandler(handler);
+                      return thread;
+                  });
         }
         @Override protected void beforeExecute(Thread t, Runnable r) {
             final boolean lessThanCorePoolSize;
@@ -262,19 +245,17 @@
         check(tpe.awaitTermination(10L, TimeUnit.MINUTES));
         checkTerminated(tpe);
 
-        //while (tg.activeCount() > 0) Thread.sleep(10);
-        //System.out.println(uncaughtExceptions);
         List<Map<Class<?>, Integer>> maps = new ArrayList<>();
         maps.add(uncaughtExceptions);
         maps.add(uncaughtExceptionsTable);
         for (Map<Class<?>, Integer> map : maps) {
-            equal(map.get(Exception.class), throwers.size());
-            equal(map.get(weird.getClass()), throwers.size());
-            equal(map.get(Error.class), throwers.size() + 1 + 2);
+            equal(map.get(Exception.class), throwers.size() + 1);
+            equal(map.get(weird.getClass()), throwers.size() + 1);
+            equal(map.get(Error.class), throwers.size() + 1);
             equal(map.get(RuntimeException.class), throwers.size() + 1);
             equal(map.size(), 4);
         }
-        equal(totalUncaughtExceptions.get(), 4L*throwers.size() + 4L);
+        equal(totalUncaughtExceptions.get(), 4*throwers.size() + 4);
 
         equal(beforeExecuteCount.get(), flakes.size());
         equal(afterExecuteCount.get(), throwers.size());
--- a/test/jdk/java/util/concurrent/tck/Collection8Test.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/concurrent/tck/Collection8Test.java	Tue Oct 03 14:00:00 2017 -0700
@@ -86,9 +86,9 @@
 
     Object bomb() {
         return new Object() {
-                public boolean equals(Object x) { throw new AssertionError(); }
-                public int hashCode() { throw new AssertionError(); }
-            };
+            public boolean equals(Object x) { throw new AssertionError(); }
+            public int hashCode() { throw new AssertionError(); }
+        };
     }
 
     /** Checks properties of empty collections. */
--- a/test/jdk/java/util/concurrent/tck/LinkedTransferQueueTest.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/concurrent/tck/LinkedTransferQueueTest.java	Tue Oct 03 14:00:00 2017 -0700
@@ -801,7 +801,7 @@
     }
 
     /**
-     * transfer waits until a poll occurs. The transfered element
+     * transfer waits until a poll occurs. The transferred element
      * is returned by the associated poll.
      */
     public void testTransfer2() throws InterruptedException {
@@ -882,7 +882,7 @@
     }
 
     /**
-     * transfer waits until a take occurs. The transfered element
+     * transfer waits until a take occurs. The transferred element
      * is returned by the associated take.
      */
     public void testTransfer5() throws InterruptedException {
--- a/test/jdk/java/util/concurrent/tck/StampedLockTest.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/concurrent/tck/StampedLockTest.java	Tue Oct 03 14:00:00 2017 -0700
@@ -1207,4 +1207,90 @@
         }
         assertUnlocked(lock);
     }
+
+    /**
+     * Stamped locks are not reentrant.
+     */
+    public void testNonReentrant() throws InterruptedException {
+        final StampedLock lock = new StampedLock();
+        long stamp;
+
+        stamp = lock.writeLock();
+        assertValid(lock, stamp);
+        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
+        assertEquals(0L, lock.tryReadLock(0L, DAYS));
+        assertValid(lock, stamp);
+        lock.unlockWrite(stamp);
+
+        stamp = lock.tryWriteLock(1L, DAYS);
+        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
+        assertValid(lock, stamp);
+        lock.unlockWrite(stamp);
+
+        stamp = lock.readLock();
+        assertEquals(0L, lock.tryWriteLock(0L, DAYS));
+        assertValid(lock, stamp);
+        lock.unlockRead(stamp);
+    }
+
+    /**
+     * """StampedLocks have no notion of ownership. Locks acquired in
+     * one thread can be released or converted in another."""
+     */
+    public void testNoOwnership() throws Throwable {
+        ArrayList<Future<?>> futures = new ArrayList<>();
+        for (Function<StampedLock, Long> writeLocker : writeLockers())
+        for (BiConsumer<StampedLock, Long> writeUnlocker : writeUnlockers()) {
+            StampedLock lock = new StampedLock();
+            long stamp = writeLocker.apply(lock);
+            futures.add(cachedThreadPool.submit(new CheckedRunnable() {
+                public void realRun() {
+                    writeUnlocker.accept(lock, stamp);
+                    assertUnlocked(lock);
+                    assertFalse(lock.validate(stamp));
+                }}));
+        }
+        for (Future<?> future : futures)
+            assertNull(future.get());
+    }
+
+    /** Tries out sample usage code from StampedLock javadoc. */
+    public void testSampleUsage() throws Throwable {
+        class Point {
+            private double x, y;
+            private final StampedLock sl = new StampedLock();
+
+            void move(double deltaX, double deltaY) { // an exclusively locked method
+                long stamp = sl.writeLock();
+                try {
+                    x += deltaX;
+                    y += deltaY;
+                } finally {
+                    sl.unlockWrite(stamp);
+                }
+            }
+
+            double distanceFromOrigin() { // A read-only method
+                double currentX, currentY;
+                long stamp = sl.tryOptimisticRead();
+                do {
+                    if (stamp == 0L)
+                        stamp = sl.readLock();
+                    try {
+                        // possibly racy reads
+                        currentX = x;
+                        currentY = y;
+                    } finally {
+                        stamp = sl.tryConvertToOptimisticRead(stamp);
+                    }
+                } while (stamp == 0);
+                return Math.hypot(currentX, currentY);
+            }
+        }
+
+        Point p = new Point();
+        p.move(3.0, 4.0);
+        assertEquals(5.0, p.distanceFromOrigin());
+    }
+
 }
--- a/test/jdk/java/util/concurrent/tck/ThreadLocalRandomTest.java	Tue Oct 03 13:55:05 2017 -0700
+++ b/test/jdk/java/util/concurrent/tck/ThreadLocalRandomTest.java	Tue Oct 03 14:00:00 2017 -0700
@@ -84,6 +84,9 @@
      * possible values.
      */
     public void testNext() throws ReflectiveOperationException {
+        // Inhibit "An illegal reflective access operation has occurred"
+        if (!testImplementationDetails) return;
+
         ThreadLocalRandom rnd = ThreadLocalRandom.current();
         final java.lang.reflect.Method m;
         try {