diff --git a/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java b/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java index 741fe3097c1..f45c0036230 100644 --- a/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java +++ b/src/java.base/share/classes/java/util/concurrent/AbstractExecutorService.java @@ -54,13 +54,13 @@ import java.util.List; * to return {@code RunnableFuture} implementations other than * {@code FutureTask}. * - *

Extension example. Here is a sketch of a class + *

Extension example. Here is a sketch of a class * that customizes {@link ThreadPoolExecutor} to use * a {@code CustomTask} class instead of the default {@code FutureTask}: *

 {@code
  * public class CustomThreadPoolExecutor extends ThreadPoolExecutor {
  *
- *   static class CustomTask implements RunnableFuture {...}
+ *   static class CustomTask implements RunnableFuture { ... }
  *
  *   protected  RunnableFuture newTaskFor(Callable c) {
  *       return new CustomTask(c);
diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java
index b14a3e8ea89..ab48a44c97a 100644
--- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java
+++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArraySet.java
@@ -69,7 +69,7 @@ import java.util.function.Predicate;
  * perform some action upon state updates.
  *
  * 
 {@code
- * class Handler { void handle(); ... }
+ * class Handler { void handle() { ... } }
  *
  * class X {
  *   private final CopyOnWriteArraySet handlers
diff --git a/src/java.base/share/classes/java/util/concurrent/CountDownLatch.java b/src/java.base/share/classes/java/util/concurrent/CountDownLatch.java
index 8d85418147b..3b41b49a605 100644
--- a/src/java.base/share/classes/java/util/concurrent/CountDownLatch.java
+++ b/src/java.base/share/classes/java/util/concurrent/CountDownLatch.java
@@ -118,7 +118,7 @@ import java.util.concurrent.locks.AbstractQueuedSynchronizer;
  * class Driver2 { // ...
  *   void main() throws InterruptedException {
  *     CountDownLatch doneSignal = new CountDownLatch(N);
- *     Executor e = ...
+ *     Executor e = ...;
  *
  *     for (int i = 0; i < N; ++i) // create and start threads
  *       e.execute(new WorkerRunnable(doneSignal, i));
@@ -135,10 +135,8 @@ import java.util.concurrent.locks.AbstractQueuedSynchronizer;
  *     this.i = i;
  *   }
  *   public void run() {
- *     try {
- *       doWork(i);
- *       doneSignal.countDown();
- *     } catch (InterruptedException ex) {} // return;
+ *     doWork();
+ *     doneSignal.countDown();
  *   }
  *
  *   void doWork() { ... }
diff --git a/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java b/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java
index 1e8ef5405aa..87e498d9c24 100644
--- a/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java
+++ b/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java
@@ -94,7 +94,9 @@ import java.util.concurrent.locks.ReentrantLock;
  *
  *     // wait until done
  *     for (Thread thread : threads)
- *       thread.join();
+ *       try {
+ *         thread.join();
+ *       } catch (InterruptedException ex) { }
  *   }
  * }}
* diff --git a/src/java.base/share/classes/java/util/concurrent/Exchanger.java b/src/java.base/share/classes/java/util/concurrent/Exchanger.java index 4d6e2d62d7c..3fae1b0b781 100644 --- a/src/java.base/share/classes/java/util/concurrent/Exchanger.java +++ b/src/java.base/share/classes/java/util/concurrent/Exchanger.java @@ -57,8 +57,8 @@ import java.util.concurrent.locks.LockSupport; *
 {@code
  * class FillAndEmpty {
  *   Exchanger exchanger = new Exchanger<>();
- *   DataBuffer initialEmptyBuffer = ... a made-up type
- *   DataBuffer initialFullBuffer = ...
+ *   DataBuffer initialEmptyBuffer = ...; // a made-up type
+ *   DataBuffer initialFullBuffer = ...;
  *
  *   class FillingLoop implements Runnable {
  *     public void run() {
@@ -69,7 +69,7 @@ import java.util.concurrent.locks.LockSupport;
  *           if (currentBuffer.isFull())
  *             currentBuffer = exchanger.exchange(currentBuffer);
  *         }
- *       } catch (InterruptedException ex) { ... handle ... }
+ *       } catch (InterruptedException ex) { ... handle ...}
  *     }
  *   }
  *
diff --git a/src/java.base/share/classes/java/util/concurrent/ExecutorService.java b/src/java.base/share/classes/java/util/concurrent/ExecutorService.java
index 9e9b63e4003..119c941a4bd 100644
--- a/src/java.base/share/classes/java/util/concurrent/ExecutorService.java
+++ b/src/java.base/share/classes/java/util/concurrent/ExecutorService.java
@@ -117,7 +117,7 @@ import java.util.List;
  *       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
  *           System.err.println("Pool did not terminate");
  *     }
- *   } catch (InterruptedException ie) {
+ *   } catch (InterruptedException ex) {
  *     // (Re-)Cancel if current thread also interrupted
  *     pool.shutdownNow();
  *     // Preserve interrupt status
diff --git a/src/java.base/share/classes/java/util/concurrent/Future.java b/src/java.base/share/classes/java/util/concurrent/Future.java
index 6099c7caf41..ebbf14dd4d1 100644
--- a/src/java.base/share/classes/java/util/concurrent/Future.java
+++ b/src/java.base/share/classes/java/util/concurrent/Future.java
@@ -56,8 +56,8 @@ package java.util.concurrent;
  * 
 {@code
  * interface ArchiveSearcher { String search(String target); }
  * class App {
- *   ExecutorService executor = ...
- *   ArchiveSearcher searcher = ...
+ *   ExecutorService executor = ...;
+ *   ArchiveSearcher searcher = ...;
  *   void showSearch(String target) throws InterruptedException {
  *     Callable task = () -> searcher.search(target);
  *     Future future = executor.submit(task);
@@ -88,25 +88,28 @@ package java.util.concurrent;
 public interface Future {
 
     /**
-     * Attempts to cancel execution of this task.  This attempt will
-     * fail if the task has already completed, has already been cancelled,
-     * or could not be cancelled for some other reason. If successful,
-     * and this task has not started when {@code cancel} is called,
-     * this task should never run.  If the task has already started,
-     * then the {@code mayInterruptIfRunning} parameter determines
-     * whether the thread executing this task should be interrupted in
-     * an attempt to stop the task.
+     * Attempts to cancel execution of this task.  This method has no
+     * effect if the task is already completed or cancelled, or could
+     * not be cancelled for some other reason.  Otherwise, if this
+     * task has not started when {@code cancel} is called, this task
+     * should never run.  If the task has already started, then the
+     * {@code mayInterruptIfRunning} parameter determines whether the
+     * thread executing this task (when known by the implementation)
+     * is interrupted in an attempt to stop the task.
      *
-     * 

After this method returns, subsequent calls to {@link #isDone} will - * always return {@code true}. Subsequent calls to {@link #isCancelled} - * will always return {@code true} if this method returned {@code true}. + *

The return value from this method does not necessarily + * indicate whether the task is now cancelled; use {@link + * #isCancelled}. * - * @param mayInterruptIfRunning {@code true} if the thread executing this - * task should be interrupted; otherwise, in-progress tasks are allowed - * to complete + * @param mayInterruptIfRunning {@code true} if the thread + * executing this task should be interrupted (if the thread is + * known to the implementation); otherwise, in-progress tasks are + * allowed to complete * @return {@code false} if the task could not be cancelled, - * typically because it has already completed normally; - * {@code true} otherwise + * typically because it has already completed; {@code true} + * otherwise. If two or more threads cause a task to be cancelled, + * then at least one of them returns {@code true}. Implementations + * may provide stronger guarantees. */ boolean cancel(boolean mayInterruptIfRunning); diff --git a/src/java.base/share/classes/java/util/concurrent/Phaser.java b/src/java.base/share/classes/java/util/concurrent/Phaser.java index 41178c29506..9c4f2a57f86 100644 --- a/src/java.base/share/classes/java/util/concurrent/Phaser.java +++ b/src/java.base/share/classes/java/util/concurrent/Phaser.java @@ -245,7 +245,7 @@ import java.util.concurrent.locks.LockSupport; * be appropriate for extremely small per-phase task bodies (thus * high rates), or up to hundreds for extremely large ones. * - *

Implementation notes: This implementation restricts the + *

Implementation notes: This implementation restricts the * maximum number of parties to 65535. Attempts to register additional * parties result in {@code IllegalStateException}. However, you can and * should create tiered phasers to accommodate arbitrarily large sets @@ -919,7 +919,7 @@ public class Phaser { *

 {@code
      * Phaser phaser = new Phaser() {
      *   protected boolean onAdvance(int phase, int parties) { return false; }
-     * }}
+ * };}
* * @param phase the current phase number on entry to this method, * before this phaser is advanced diff --git a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java index ef239b1baa6..908a59de469 100644 --- a/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java @@ -87,7 +87,7 @@ import jdk.internal.util.ArraysSupport; *
 {@code
  * class FIFOEntry>
  *     implements Comparable> {
- *   static final AtomicLong seq = new AtomicLong(0);
+ *   static final AtomicLong seq = new AtomicLong();
  *   final long seqNum;
  *   final E entry;
  *   public FIFOEntry(E entry) {
@@ -290,7 +290,9 @@ public class PriorityBlockingQueue extends AbstractQueue
         if (allocationSpinLock == 0 &&
             ALLOCATIONSPINLOCK.compareAndSet(this, 0, 1)) {
             try {
-                int growth = oldCap < 64 ? oldCap + 2 : oldCap >> 1;
+                int growth = (oldCap < 64)
+                    ? (oldCap + 2) // grow faster if small
+                    : (oldCap >> 1);
                 int newCap = ArraysSupport.newLength(oldCap, 1, growth);
                 if (queue == array)
                     newArray = new Object[newCap];
diff --git a/src/java.base/share/classes/java/util/concurrent/Semaphore.java b/src/java.base/share/classes/java/util/concurrent/Semaphore.java
index 86ee638f78d..5c299659d6a 100644
--- a/src/java.base/share/classes/java/util/concurrent/Semaphore.java
+++ b/src/java.base/share/classes/java/util/concurrent/Semaphore.java
@@ -66,7 +66,7 @@ import java.util.concurrent.locks.AbstractQueuedSynchronizer;
  *
  *   // Not a particularly efficient data structure; just for demo
  *
- *   protected Object[] items = ... whatever kinds of items being managed
+ *   protected Object[] items = ...; // whatever kinds of items being managed
  *   protected boolean[] used = new boolean[MAX_AVAILABLE];
  *
  *   protected synchronized Object getNextAvailableItem() {
diff --git a/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java b/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java
index 9efb01d1a0d..e3c2a6098d8 100644
--- a/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java
+++ b/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java
@@ -41,6 +41,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.locks.LockSupport;
+import java.util.concurrent.locks.ReentrantLock;
 import java.util.function.BiConsumer;
 import java.util.function.BiPredicate;
 import java.util.function.Consumer;
@@ -175,11 +176,11 @@ public class SubmissionPublisher implements Publisher,
     /*
      * Most mechanics are handled by BufferedSubscription. This class
      * mainly tracks subscribers and ensures sequentiality, by using
-     * built-in synchronization locks across public methods. Using
-     * built-in locks works well in the most typical case in which
-     * only one thread submits items. We extend this idea in
-     * submission methods by detecting single-ownership to reduce
-     * producer-consumer synchronization strength.
+     * locks across public methods, to ensure thread-safety in the
+     * presence of multiple sources and maintain acquire-release
+     * ordering around user operations. However, we also track whether
+     * there is only a single source, and if so streamline some buffer
+     * operations by avoiding some atomics.
      */
 
     /** The largest possible power of two array size. */
@@ -234,6 +235,8 @@ public class SubmissionPublisher implements Publisher,
      */
     BufferedSubscription clients;
 
+    /** Lock for exclusion across multiple sources */
+    final ReentrantLock lock;
     /** Run status, updated only within locks */
     volatile boolean closed;
     /** Set true on first call to subscribe, to initialize possible owner */
@@ -274,6 +277,7 @@ public class SubmissionPublisher implements Publisher,
             throw new NullPointerException();
         if (maxBufferCapacity <= 0)
             throw new IllegalArgumentException("capacity must be positive");
+        this.lock = new ReentrantLock();
         this.executor = executor;
         this.onNextHandler = handler;
         this.maxBufferCapacity = roundCapacity(maxBufferCapacity);
@@ -337,13 +341,15 @@ public class SubmissionPublisher implements Publisher,
      */
     public void subscribe(Subscriber subscriber) {
         if (subscriber == null) throw new NullPointerException();
+        ReentrantLock lock = this.lock;
         int max = maxBufferCapacity; // allocate initial array
         Object[] array = new Object[max < INITIAL_CAPACITY ?
                                     max : INITIAL_CAPACITY];
         BufferedSubscription subscription =
             new BufferedSubscription(subscriber, executor, onNextHandler,
                                         array, max);
-        synchronized (this) {
+        lock.lock();
+        try {
             if (!subscribed) {
                 subscribed = true;
                 owner = Thread.currentThread();
@@ -378,6 +384,8 @@ public class SubmissionPublisher implements Publisher,
                     pred = b;
                 b = next;
             }
+        } finally {
+            lock.unlock();
         }
     }
 
@@ -390,7 +398,9 @@ public class SubmissionPublisher implements Publisher,
         if (item == null) throw new NullPointerException();
         int lag = 0;
         boolean complete, unowned;
-        synchronized (this) {
+        ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
             Thread t = Thread.currentThread(), o;
             BufferedSubscription b = clients;
             if ((unowned = ((o = owner) != t)) && o != null)
@@ -421,6 +431,8 @@ public class SubmissionPublisher implements Publisher,
                 if (retries != null || cleanMe)
                     lag = retryOffer(item, nanos, onDrop, retries, lag, cleanMe);
             }
+        } finally {
+            lock.unlock();
         }
         if (complete)
             throw new IllegalStateException("Closed");
@@ -609,14 +621,18 @@ public class SubmissionPublisher implements Publisher,
      * subscribers have yet completed.
      */
     public void close() {
+        ReentrantLock lock = this.lock;
         if (!closed) {
             BufferedSubscription b;
-            synchronized (this) {
+            lock.lock();
+            try {
                 // no need to re-check closed here
                 b = clients;
                 clients = null;
                 owner = null;
                 closed = true;
+            } finally {
+                lock.unlock();
             }
             while (b != null) {
                 BufferedSubscription next = b.next;
@@ -641,9 +657,11 @@ public class SubmissionPublisher implements Publisher,
     public void closeExceptionally(Throwable error) {
         if (error == null)
             throw new NullPointerException();
+        ReentrantLock lock = this.lock;
         if (!closed) {
             BufferedSubscription b;
-            synchronized (this) {
+            lock.lock();
+            try {
                 b = clients;
                 if (!closed) {  // don't clobber racing close
                     closedException = error;
@@ -651,6 +669,8 @@ public class SubmissionPublisher implements Publisher,
                     owner = null;
                     closed = true;
                 }
+            } finally {
+                lock.unlock();
             }
             while (b != null) {
                 BufferedSubscription next = b.next;
@@ -688,7 +708,9 @@ public class SubmissionPublisher implements Publisher,
      */
     public boolean hasSubscribers() {
         boolean nonEmpty = false;
-        synchronized (this) {
+        ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
             for (BufferedSubscription b = clients; b != null;) {
                 BufferedSubscription next = b.next;
                 if (b.isClosed()) {
@@ -700,6 +722,8 @@ public class SubmissionPublisher implements Publisher,
                     break;
                 }
             }
+        } finally {
+            lock.unlock();
         }
         return nonEmpty;
     }
@@ -710,9 +734,15 @@ public class SubmissionPublisher implements Publisher,
      * @return the number of current subscribers
      */
     public int getNumberOfSubscribers() {
-        synchronized (this) {
-            return cleanAndCount();
+        int n;
+        ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
+            n = cleanAndCount();
+        } finally {
+            lock.unlock();
         }
+        return n;
     }
 
     /**
@@ -742,7 +772,9 @@ public class SubmissionPublisher implements Publisher,
      */
     public List> getSubscribers() {
         ArrayList> subs = new ArrayList<>();
-        synchronized (this) {
+        ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
             BufferedSubscription pred = null, next;
             for (BufferedSubscription b = clients; b != null; b = next) {
                 next = b.next;
@@ -758,6 +790,8 @@ public class SubmissionPublisher implements Publisher,
                     pred = b;
                 }
             }
+        } finally {
+            lock.unlock();
         }
         return subs;
     }
@@ -771,8 +805,11 @@ public class SubmissionPublisher implements Publisher,
      */
     public boolean isSubscribed(Subscriber subscriber) {
         if (subscriber == null) throw new NullPointerException();
+        boolean subscribed = false;
+        ReentrantLock lock = this.lock;
         if (!closed) {
-            synchronized (this) {
+            lock.lock();
+            try {
                 BufferedSubscription pred = null, next;
                 for (BufferedSubscription b = clients; b != null; b = next) {
                     next = b.next;
@@ -783,14 +820,16 @@ public class SubmissionPublisher implements Publisher,
                         else
                             pred.next = next;
                     }
-                    else if (subscriber.equals(b.subscriber))
-                        return true;
+                    else if (subscribed = subscriber.equals(b.subscriber))
+                        break;
                     else
                         pred = b;
                 }
+            } finally {
+                lock.unlock();
             }
         }
-        return false;
+        return subscribed;
     }
 
     /**
@@ -803,7 +842,9 @@ public class SubmissionPublisher implements Publisher,
     public long estimateMinimumDemand() {
         long min = Long.MAX_VALUE;
         boolean nonEmpty = false;
-        synchronized (this) {
+        ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
             BufferedSubscription pred = null, next;
             for (BufferedSubscription b = clients; b != null; b = next) {
                 int n; long d;
@@ -822,6 +863,8 @@ public class SubmissionPublisher implements Publisher,
                     pred = b;
                 }
             }
+        } finally {
+            lock.unlock();
         }
         return nonEmpty ? min : 0;
     }
@@ -834,7 +877,9 @@ public class SubmissionPublisher implements Publisher,
      */
     public int estimateMaximumLag() {
         int max = 0;
-        synchronized (this) {
+        ReentrantLock lock = this.lock;
+        lock.lock();
+        try {
             BufferedSubscription pred = null, next;
             for (BufferedSubscription b = clients; b != null; b = next) {
                 int n;
@@ -852,6 +897,8 @@ public class SubmissionPublisher implements Publisher,
                     pred = b;
                 }
             }
+        } finally {
+            lock.unlock();
         }
         return max;
     }
diff --git a/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java
index 5c61ab0855e..b5dcd794b13 100644
--- a/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java
+++ b/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java
@@ -221,13 +221,18 @@ import java.util.concurrent.locks.ReentrantLock;
  * simple feedback control mechanism that will slow down the rate that
  * new tasks are submitted.
  *
- * 
  • In {@link ThreadPoolExecutor.DiscardPolicy}, a task that - * cannot be executed is simply dropped. + *
  • In {@link ThreadPoolExecutor.DiscardPolicy}, a task that cannot + * be executed is simply dropped. This policy is designed only for + * those rare cases in which task completion is never relied upon. * *
  • In {@link ThreadPoolExecutor.DiscardOldestPolicy}, if the * executor is not shut down, the task at the head of the work queue * is dropped, and then execution is retried (which can fail again, - * causing this to be repeated.) + * causing this to be repeated.) This policy is rarely acceptable. In + * nearly all cases, you should also cancel the task to cause an + * exception in any component waiting for its completion, and/or log + * the failure, as illustrated in {@link + * ThreadPoolExecutor.DiscardOldestPolicy} documentation. * * * @@ -272,7 +277,7 @@ import java.util.concurrent.locks.ReentrantLock; * * * - *

    Extension example. Most extensions of this class + *

    Extension example. Most extensions of this class * override one or more of the protected hook methods. For example, * here is a subclass that adds a simple pause/resume feature: * @@ -1149,8 +1154,10 @@ public class ThreadPoolExecutor extends AbstractExecutorService { /** * Creates a new {@code ThreadPoolExecutor} with the given initial - * parameters, the default thread factory and the default rejected - * execution handler. + * parameters, the + * {@linkplain Executors#defaultThreadFactory default thread factory} + * and the {@linkplain ThreadPoolExecutor.AbortPolicy + * default rejected execution handler}. * *

    It may be more convenient to use one of the {@link Executors} * factory methods instead of this general purpose constructor. @@ -1184,7 +1191,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { /** * Creates a new {@code ThreadPoolExecutor} with the given initial - * parameters and {@linkplain ThreadPoolExecutor.AbortPolicy + * parameters and the {@linkplain ThreadPoolExecutor.AbortPolicy * default rejected execution handler}. * * @param corePoolSize the number of threads to keep in the pool, even @@ -1220,7 +1227,7 @@ public class ThreadPoolExecutor extends AbstractExecutorService { /** * Creates a new {@code ThreadPoolExecutor} with the given initial - * parameters and + * parameters and the * {@linkplain Executors#defaultThreadFactory default thread factory}. * * @param corePoolSize the number of threads to keep in the pool, even @@ -2081,7 +2088,20 @@ public class ThreadPoolExecutor extends AbstractExecutorService { /** * A handler for rejected tasks that discards the oldest unhandled * request and then retries {@code execute}, unless the executor - * is shut down, in which case the task is discarded. + * is shut down, in which case the task is discarded. This policy is + * rarely useful in cases where other threads may be waiting for + * tasks to terminate, or failures must be recorded. Instead consider + * using a handler of the form: + *

     {@code
    +     * new RejectedExecutionHandler() {
    +     *   public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
    +     *     Runnable dropped = e.getQueue().poll();
    +     *     if (dropped instanceof Future) {
    +     *       ((Future)dropped).cancel(false);
    +     *       // also consider logging the failure
    +     *     }
    +     *     e.execute(r);  // retry
    +     * }}}
    */ public static class DiscardOldestPolicy implements RejectedExecutionHandler { /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java index caff3c423e3..1555c22caa4 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java @@ -68,9 +68,8 @@ public class AtomicBoolean implements java.io.Serializable { * @param initialValue the initial value */ public AtomicBoolean(boolean initialValue) { - if (initialValue) { + if (initialValue) value = 1; - } } /** diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java index 7f70f1e893f..fea91ff0ab2 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -62,7 +62,7 @@ import java.lang.invoke.VarHandle; * * private static final AtomicReferenceFieldUpdater leftUpdater = * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "left"); - * private static AtomicReferenceFieldUpdater rightUpdater = + * private static final AtomicReferenceFieldUpdater rightUpdater = * AtomicReferenceFieldUpdater.newUpdater(Node.class, Node.class, "right"); * * Node getLeft() { return left; } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java index 9e62a2cb2a2..d04b8253ee7 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java @@ -111,16 +111,17 @@ public class DoubleAccumulator extends Striped64 implements Serializable { || ((r = doubleToRawLongBits (function.applyAsDouble(longBitsToDouble(b = base), x))) != b && !casBase(b, r))) { + int index = getProbe(); boolean uncontended = true; if (cs == null || (m = cs.length - 1) < 0 - || (c = cs[getProbe() & m]) == null + || (c = cs[index & m]) == null || !(uncontended = ((r = doubleToRawLongBits (function.applyAsDouble (longBitsToDouble(v = c.value), x))) == v) || c.cas(v, r))) - doubleAccumulate(x, function, uncontended); + doubleAccumulate(x, function, uncontended, index); } } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java index 1d1a42e0f61..70a714e168a 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAdder.java @@ -92,13 +92,14 @@ public class DoubleAdder extends Striped64 implements Serializable { !casBase(b = base, Double.doubleToRawLongBits (Double.longBitsToDouble(b) + x))) { + int index = getProbe(); boolean uncontended = true; if (cs == null || (m = cs.length - 1) < 0 || - (c = cs[getProbe() & m]) == null || + (c = cs[index & m]) == null || !(uncontended = c.cas(v = c.value, Double.doubleToRawLongBits (Double.longBitsToDouble(v) + x)))) - doubleAccumulate(x, null, uncontended); + doubleAccumulate(x, null, uncontended, index); } } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java index 39c53d20999..be96853ce09 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java @@ -108,14 +108,15 @@ public class LongAccumulator extends Striped64 implements Serializable { if ((cs = cells) != null || ((r = function.applyAsLong(b = base, x)) != b && !casBase(b, r))) { + int index = getProbe(); boolean uncontended = true; if (cs == null || (m = cs.length - 1) < 0 - || (c = cs[getProbe() & m]) == null + || (c = cs[index & m]) == null || !(uncontended = (r = function.applyAsLong(v = c.value, x)) == v || c.cas(v, r))) - longAccumulate(x, function, uncontended); + longAccumulate(x, function, uncontended, index); } } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java b/src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java index 08466abbb8a..c069249a535 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/LongAdder.java @@ -85,11 +85,12 @@ public class LongAdder extends Striped64 implements Serializable { public void add(long x) { Cell[] cs; long b, v; int m; Cell c; if ((cs = cells) != null || !casBase(b = base, b + x)) { + int index = getProbe(); boolean uncontended = true; if (cs == null || (m = cs.length - 1) < 0 || - (c = cs[getProbe() & m]) == null || + (c = cs[index & m]) == null || !(uncontended = c.cas(v = c.value, v + x))) - longAccumulate(x, null, uncontended); + longAccumulate(x, null, uncontended, index); } } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java b/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java index 9c21fa36e5a..7b44eca5af8 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java @@ -125,7 +125,7 @@ abstract class Striped64 extends Number { volatile long value; Cell(long x) { value = x; } final boolean cas(long cmp, long val) { - return VALUE.compareAndSet(this, cmp, val); + return VALUE.weakCompareAndSetRelease(this, cmp, val); } final void reset() { VALUE.setVolatile(this, 0L); @@ -178,7 +178,7 @@ abstract class Striped64 extends Number { * CASes the base field. */ final boolean casBase(long cmp, long val) { - return BASE.compareAndSet(this, cmp, val); + return BASE.weakCompareAndSetRelease(this, cmp, val); } final long getAndSetBase(long val) { @@ -224,20 +224,19 @@ abstract class Striped64 extends Number { * @param fn the update function, or null for add (this convention * avoids the need for an extra field or function in LongAdder). * @param wasUncontended false if CAS failed before call + * @param index thread index from getProbe */ final void longAccumulate(long x, LongBinaryOperator fn, - boolean wasUncontended) { - int h; - if ((h = getProbe()) == 0) { + boolean wasUncontended, int index) { + if (index == 0) { ThreadLocalRandom.current(); // force initialization - h = getProbe(); + index = getProbe(); wasUncontended = true; } - boolean collide = false; // True if last slot nonempty - done: for (;;) { + for (boolean collide = false;;) { // True if last slot nonempty Cell[] cs; Cell c; int n; long v; if ((cs = cells) != null && (n = cs.length) > 0) { - if ((c = cs[(n - 1) & h]) == null) { + if ((c = cs[(n - 1) & index]) == null) { if (cellsBusy == 0) { // Try to attach new Cell Cell r = new Cell(x); // Optimistically create if (cellsBusy == 0 && casCellsBusy()) { @@ -245,9 +244,9 @@ abstract class Striped64 extends Number { Cell[] rs; int m, j; if ((rs = cells) != null && (m = rs.length) > 0 && - rs[j = (m - 1) & h] == null) { + rs[j = (m - 1) & index] == null) { rs[j] = r; - break done; + break; } } finally { cellsBusy = 0; @@ -276,15 +275,15 @@ abstract class Striped64 extends Number { collide = false; continue; // Retry with expanded table } - h = advanceProbe(h); + index = advanceProbe(index); } else if (cellsBusy == 0 && cells == cs && casCellsBusy()) { try { // Initialize table if (cells == cs) { Cell[] rs = new Cell[2]; - rs[h & 1] = new Cell(x); + rs[index & 1] = new Cell(x); cells = rs; - break done; + break; } } finally { cellsBusy = 0; @@ -293,7 +292,7 @@ abstract class Striped64 extends Number { // Fall back on using base else if (casBase(v = base, (fn == null) ? v + x : fn.applyAsLong(v, x))) - break done; + break; } } @@ -310,18 +309,16 @@ abstract class Striped64 extends Number { * maintained by copy/paste/adapt. */ final void doubleAccumulate(double x, DoubleBinaryOperator fn, - boolean wasUncontended) { - int h; - if ((h = getProbe()) == 0) { + boolean wasUncontended, int index) { + if (index == 0) { ThreadLocalRandom.current(); // force initialization - h = getProbe(); + index = getProbe(); wasUncontended = true; } - boolean collide = false; // True if last slot nonempty - done: for (;;) { + for (boolean collide = false;;) { // True if last slot nonempty Cell[] cs; Cell c; int n; long v; if ((cs = cells) != null && (n = cs.length) > 0) { - if ((c = cs[(n - 1) & h]) == null) { + if ((c = cs[(n - 1) & index]) == null) { if (cellsBusy == 0) { // Try to attach new Cell Cell r = new Cell(Double.doubleToRawLongBits(x)); if (cellsBusy == 0 && casCellsBusy()) { @@ -329,9 +326,9 @@ abstract class Striped64 extends Number { Cell[] rs; int m, j; if ((rs = cells) != null && (m = rs.length) > 0 && - rs[j = (m - 1) & h] == null) { + rs[j = (m - 1) & index] == null) { rs[j] = r; - break done; + break; } } finally { cellsBusy = 0; @@ -359,15 +356,15 @@ abstract class Striped64 extends Number { collide = false; continue; // Retry with expanded table } - h = advanceProbe(h); + index = advanceProbe(index); } else if (cellsBusy == 0 && cells == cs && casCellsBusy()) { try { // Initialize table if (cells == cs) { Cell[] rs = new Cell[2]; - rs[h & 1] = new Cell(Double.doubleToRawLongBits(x)); + rs[index & 1] = new Cell(Double.doubleToRawLongBits(x)); cells = rs; - break done; + break; } } finally { cellsBusy = 0; @@ -375,7 +372,7 @@ abstract class Striped64 extends Number { } // Fall back on using base else if (casBase(v = base, apply(fn, v, x))) - break done; + break; } } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java b/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java index 8390ff35d0b..ef3c08b4a2c 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/package-info.java @@ -54,7 +54,7 @@ *
     {@code
      * class Sequencer {
      *   private final AtomicLong sequenceNumber
    - *     = new AtomicLong(0);
    + *     = new AtomicLong(17);
      *   public long next() {
      *     return sequenceNumber.getAndIncrement();
      *   }
    diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
    index 83b434ff7a1..73e04fc9028 100644
    --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
    +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
    @@ -137,13 +137,13 @@ import jdk.internal.misc.Unsafe;
      * of exclusive synchronization takes the form:
      *
      * 
    - * Acquire:
    + * Acquire:
      *     while (!tryAcquire(arg)) {
      *        enqueue thread if it is not already queued;
      *        possibly block current thread;
      *     }
      *
    - * Release:
    + * Release:
      *     if (tryRelease(arg))
      *        unblock the first queued thread;
      * 
    diff --git a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java index be46131d3e2..c58925b086e 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java @@ -550,7 +550,7 @@ public class ReentrantLock implements Lock, java.io.Serializable { * *
     {@code
          * class X {
    -     *   ReentrantLock lock = new ReentrantLock();
    +     *   final ReentrantLock lock = new ReentrantLock();
          *   // ...
          *   public void m() {
          *     assert lock.getHoldCount() == 0;
    @@ -580,7 +580,7 @@ public class ReentrantLock implements Lock, java.io.Serializable {
          *
          * 
     {@code
          * class X {
    -     *   ReentrantLock lock = new ReentrantLock();
    +     *   final ReentrantLock lock = new ReentrantLock();
          *   // ...
          *
          *   public void m() {
    @@ -594,7 +594,7 @@ public class ReentrantLock implements Lock, java.io.Serializable {
          *
          * 
     {@code
          * class X {
    -     *   ReentrantLock lock = new ReentrantLock();
    +     *   final ReentrantLock lock = new ReentrantLock();
          *   // ...
          *
          *   public void m() {
    diff --git a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java
    index 843a18c5f99..c73bd41cea8 100644
    --- a/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java
    +++ b/src/java.base/share/classes/java/util/concurrent/locks/ReentrantReadWriteLock.java
    @@ -128,7 +128,7 @@ import jdk.internal.vm.annotation.ReservedStackAccess;
      * locks: a deserialized lock is in the unlocked state, regardless of
      * its state when serialized.
      *
    - * 

    Sample usages. Here is a code sketch showing how to perform + *

    Sample usages. Here is a code sketch showing how to perform * lock downgrading after updating a cache (exception handling is * particularly tricky when handling multiple locks in a non-nested * fashion): @@ -149,7 +149,7 @@ import jdk.internal.vm.annotation.ReservedStackAccess; * // Recheck state because another thread might have * // acquired write lock and changed state before we did. * if (!cacheValid) { - * data = ... + * data = ...; * cacheValid = true; * } * // Downgrade by acquiring read lock before releasing write lock diff --git a/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java b/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java index b13df1ce381..b9f0e9340b7 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/StampedLock.java @@ -212,8 +212,8 @@ import jdk.internal.vm.annotation.ReservedStackAccess; * } * } * - * // Upgrade read lock to write lock - * void moveIfAtOrigin(double newX, double newY) { + * // upgrade read lock to write lock + * void moveIfAtOrigin2(double newX, double newY) { * long stamp = sl.readLock(); * try { * while (x == 0.0 && y == 0.0) { diff --git a/test/jdk/java/util/Collection/IteratorMicroBenchmark.java b/test/jdk/java/util/Collection/IteratorMicroBenchmark.java index 72902d33ef6..45426cc6127 100644 --- a/test/jdk/java/util/Collection/IteratorMicroBenchmark.java +++ b/test/jdk/java/util/Collection/IteratorMicroBenchmark.java @@ -360,7 +360,6 @@ public class IteratorMicroBenchmark { } Stream jobs(Collection x) { - final String klazz = goodClassName(x); return concatStreams( collectionJobs(x), diff --git a/test/jdk/java/util/concurrent/ExecutorService/Invoke.java b/test/jdk/java/util/concurrent/ExecutorService/Invoke.java index 918c9acdde0..a999a14388e 100644 --- a/test/jdk/java/util/concurrent/ExecutorService/Invoke.java +++ b/test/jdk/java/util/concurrent/ExecutorService/Invoke.java @@ -84,9 +84,16 @@ public class Invoke { public static void main(String[] args) { try { - testInvokeAll(); - testInvokeAny(); - testInvokeAny_cancellationInterrupt(); + for (int nThreads = 1; nThreads <= 6; ++nThreads) { + // untimed + testInvokeAll(nThreads, false); + testInvokeAny(nThreads, false); + testInvokeAny_cancellationInterrupt(nThreads, false); + // timed + testInvokeAll(nThreads, true); + testInvokeAny(nThreads, true); + testInvokeAny_cancellationInterrupt(nThreads, true); + } } catch (Throwable t) { unexpected(t); } if (failed > 0) @@ -96,10 +103,8 @@ public class Invoke { static final long timeoutSeconds = 10L; - static void testInvokeAll() throws Throwable { + static void testInvokeAll(int nThreads, boolean timed) throws Throwable { final ThreadLocalRandom rnd = ThreadLocalRandom.current(); - final int nThreads = rnd.nextInt(2, 7); - final boolean timed = rnd.nextBoolean(); final ExecutorService pool = Executors.newFixedThreadPool(nThreads); final AtomicLong count = new AtomicLong(0); class Task implements Callable { @@ -136,17 +141,15 @@ public class Invoke { } } - static void testInvokeAny() throws Throwable { + static void testInvokeAny(int nThreads, boolean timed) throws Throwable { final ThreadLocalRandom rnd = ThreadLocalRandom.current(); - final boolean timed = rnd.nextBoolean(); - final ExecutorService pool = Executors.newSingleThreadExecutor(); + final ExecutorService pool = Executors.newFixedThreadPool(nThreads); final AtomicLong count = new AtomicLong(0); final CountDownLatch invokeAnyDone = new CountDownLatch(1); class Task implements Callable { public Long call() throws Exception { long x = count.incrementAndGet(); - check(x <= 2); - if (x == 2) { + if (x > 1) { // wait for main thread to interrupt us ... awaitInterrupt(timeoutSeconds); // ... and then for invokeAny to return @@ -173,12 +176,12 @@ public class Invoke { check(val == 1); invokeAnyDone.countDown(); - // inherent race between main thread interrupt and - // start of second task - check(count.get() == 1 || count.get() == 2); - pool.shutdown(); check(pool.awaitTermination(timeoutSeconds, SECONDS)); + + long c = count.get(); + check(c >= 1 && c <= tasks.size()); + } finally { pool.shutdownNow(); } @@ -187,18 +190,16 @@ public class Invoke { /** * Every remaining running task is sent an interrupt for cancellation. */ - static void testInvokeAny_cancellationInterrupt() throws Throwable { + static void testInvokeAny_cancellationInterrupt(int nThreads, boolean timed) throws Throwable { final ThreadLocalRandom rnd = ThreadLocalRandom.current(); - final int nThreads = rnd.nextInt(2, 7); - final boolean timed = rnd.nextBoolean(); final ExecutorService pool = Executors.newFixedThreadPool(nThreads); final AtomicLong count = new AtomicLong(0); final AtomicLong interruptedCount = new AtomicLong(0); final CyclicBarrier allStarted = new CyclicBarrier(nThreads); class Task implements Callable { public Long call() throws Exception { - allStarted.await(); long x = count.incrementAndGet(); + allStarted.await(); if (x > 1) // main thread will interrupt us awaitInterrupt(timeoutSeconds); diff --git a/test/jdk/java/util/concurrent/tck/ArrayBlockingQueueTest.java b/test/jdk/java/util/concurrent/tck/ArrayBlockingQueueTest.java index 0a783d70689..61d1d4f5762 100644 --- a/test/jdk/java/util/concurrent/tck/ArrayBlockingQueueTest.java +++ b/test/jdk/java/util/concurrent/tck/ArrayBlockingQueueTest.java @@ -715,7 +715,7 @@ public class ArrayBlockingQueueTest extends JSR166TestCase { Integer x = (Integer) it.next(); assertEquals(s + i, (int) x); for (Object[] a : as) - assertSame(a1[i], x); + assertSame(a[i], x); } } diff --git a/test/jdk/java/util/concurrent/tck/ArrayDequeTest.java b/test/jdk/java/util/concurrent/tck/ArrayDequeTest.java index 88f70a50d9d..0ed9159d229 100644 --- a/test/jdk/java/util/concurrent/tck/ArrayDequeTest.java +++ b/test/jdk/java/util/concurrent/tck/ArrayDequeTest.java @@ -738,7 +738,7 @@ public class ArrayDequeTest extends JSR166TestCase { Integer x = (Integer) it.next(); assertEquals(s + i, (int) x); for (Object[] a : as) - assertSame(a1[i], x); + assertSame(a[i], x); } } diff --git a/test/jdk/java/util/concurrent/tck/ArrayListTest.java b/test/jdk/java/util/concurrent/tck/ArrayListTest.java index 203c04c6ea9..56ddb49ff0b 100644 --- a/test/jdk/java/util/concurrent/tck/ArrayListTest.java +++ b/test/jdk/java/util/concurrent/tck/ArrayListTest.java @@ -57,7 +57,7 @@ public class ArrayListTest extends JSR166TestCase { } } return newTestSuite( - // ArrayListTest.class, + ArrayListTest.class, CollectionTest.testSuite(new Implementation()), CollectionTest.testSuite(new SubListImplementation())); } diff --git a/test/jdk/java/util/concurrent/tck/Collection8Test.java b/test/jdk/java/util/concurrent/tck/Collection8Test.java index 807ff490367..e90d52bba46 100644 --- a/test/jdk/java/util/concurrent/tck/Collection8Test.java +++ b/test/jdk/java/util/concurrent/tck/Collection8Test.java @@ -440,7 +440,6 @@ public class Collection8Test extends JSR166TestCase { if (rnd.nextBoolean()) assertTrue(it.hasNext()); it.next(); } - Consumer alwaysThrows = e -> { throw new AssertionError(); }; // TODO: many more removal methods if (rnd.nextBoolean()) { for (Iterator z = c.iterator(); z.hasNext(); ) { @@ -661,7 +660,6 @@ public class Collection8Test extends JSR166TestCase { */ public void testStreamForEach() throws Throwable { final Collection c = impl.emptyCollection(); - final AtomicLong count = new AtomicLong(0L); final Object x = impl.makeElement(1); final Object y = impl.makeElement(2); final ArrayList found = new ArrayList(); @@ -719,7 +717,6 @@ public class Collection8Test extends JSR166TestCase { */ public void testForEach() throws Throwable { final Collection c = impl.emptyCollection(); - final AtomicLong count = new AtomicLong(0L); final Object x = impl.makeElement(1); final Object y = impl.makeElement(2); final ArrayList found = new ArrayList(); diff --git a/test/jdk/java/util/concurrent/tck/CompletableFutureTest.java b/test/jdk/java/util/concurrent/tck/CompletableFutureTest.java index 2f940855e63..7b03ecd5d21 100644 --- a/test/jdk/java/util/concurrent/tck/CompletableFutureTest.java +++ b/test/jdk/java/util/concurrent/tck/CompletableFutureTest.java @@ -3778,16 +3778,6 @@ public class CompletableFutureTest extends JSR166TestCase { checkCompletedExceptionally(f, ex); } - /** - * failedFuture(null) throws NPE - */ - public void testFailedFuture_null() { - try { - CompletableFuture f = CompletableFuture.failedFuture(null); - shouldThrow(); - } catch (NullPointerException success) {} - } - /** * copy returns a CompletableFuture that is completed normally, * with the same value, when source is. @@ -4217,12 +4207,9 @@ public class CompletableFutureTest extends JSR166TestCase { // Manufacture boxed primitives for primitive params for (int i = 0; i < args.length; i++) { Class type = parameterTypes[i]; - if (parameterTypes[i] == boolean.class) - args[i] = false; - else if (parameterTypes[i] == int.class) - args[i] = 0; - else if (parameterTypes[i] == long.class) - args[i] = 0L; + if (type == boolean.class) args[i] = false; + else if (type == int.class) args[i] = 0; + else if (type == long.class) args[i] = 0L; } for (CompletionStage stage : stages) { try { diff --git a/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java b/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java index e193c923921..e6861c077c8 100644 --- a/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java +++ b/test/jdk/java/util/concurrent/tck/ConcurrentLinkedDequeTest.java @@ -1010,7 +1010,6 @@ public class ConcurrentLinkedDequeTest extends JSR166TestCase { * ant -Djsr166.expensiveTests=true -Djsr166.tckTestClass=ConcurrentLinkedDequeTest -Djsr166.methodFilter=testBug8189387 tck */ public void testBug8189387() { - final ThreadLocalRandom rnd = ThreadLocalRandom.current(); Object x = new Object(); for (int n = expensiveTests ? 100_000 : 10; n--> 0; ) { ConcurrentLinkedDeque d = new ConcurrentLinkedDeque<>(); diff --git a/test/jdk/java/util/concurrent/tck/ExecutorsTest.java b/test/jdk/java/util/concurrent/tck/ExecutorsTest.java index faf72c72929..a2e9f1ba36c 100644 --- a/test/jdk/java/util/concurrent/tck/ExecutorsTest.java +++ b/test/jdk/java/util/concurrent/tck/ExecutorsTest.java @@ -90,7 +90,7 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testNewCachedThreadPool3() { try { - ExecutorService e = Executors.newCachedThreadPool(null); + ExecutorService unused = Executors.newCachedThreadPool(null); shouldThrow(); } catch (NullPointerException success) {} } @@ -124,7 +124,7 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testNewSingleThreadExecutor3() { try { - ExecutorService e = Executors.newSingleThreadExecutor(null); + ExecutorService unused = Executors.newSingleThreadExecutor(null); shouldThrow(); } catch (NullPointerException success) {} } @@ -172,7 +172,7 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testNewFixedThreadPool3() { try { - ExecutorService e = Executors.newFixedThreadPool(2, null); + ExecutorService unused = Executors.newFixedThreadPool(2, null); shouldThrow(); } catch (NullPointerException success) {} } @@ -182,7 +182,7 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testNewFixedThreadPool4() { try { - ExecutorService e = Executors.newFixedThreadPool(0); + ExecutorService unused = Executors.newFixedThreadPool(0); shouldThrow(); } catch (IllegalArgumentException success) {} } @@ -204,7 +204,8 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testUnconfigurableExecutorServiceNPE() { try { - ExecutorService e = Executors.unconfigurableExecutorService(null); + ExecutorService unused = + Executors.unconfigurableExecutorService(null); shouldThrow(); } catch (NullPointerException success) {} } @@ -214,7 +215,8 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testUnconfigurableScheduledExecutorServiceNPE() { try { - ExecutorService e = Executors.unconfigurableScheduledExecutorService(null); + ExecutorService unused = + Executors.unconfigurableScheduledExecutorService(null); shouldThrow(); } catch (NullPointerException success) {} } @@ -304,9 +306,11 @@ public class ExecutorsTest extends JSR166TestCase { Executors.newScheduledThreadPool(2), }; - final Runnable sleeper = new CheckedInterruptedRunnable() { + final CountDownLatch done = new CountDownLatch(1); + + final Runnable sleeper = new CheckedRunnable() { public void realRun() throws InterruptedException { - delay(LONG_DELAY_MS); + done.await(LONG_DELAY_MS, MILLISECONDS); }}; List threads = new ArrayList<>(); @@ -319,6 +323,7 @@ public class ExecutorsTest extends JSR166TestCase { } for (Thread thread : threads) awaitTermination(thread); + done.countDown(); for (ExecutorService executor : executors) joinPool(executor); } @@ -578,7 +583,7 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testCallableNPE1() { try { - Callable c = Executors.callable((Runnable) null); + Callable unused = Executors.callable((Runnable) null); shouldThrow(); } catch (NullPointerException success) {} } @@ -588,7 +593,7 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testCallableNPE2() { try { - Callable c = Executors.callable((Runnable) null, one); + Callable unused = Executors.callable((Runnable) null, one); shouldThrow(); } catch (NullPointerException success) {} } @@ -598,7 +603,7 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testCallableNPE3() { try { - Callable c = Executors.callable((PrivilegedAction) null); + Callable unused = Executors.callable((PrivilegedAction) null); shouldThrow(); } catch (NullPointerException success) {} } @@ -608,7 +613,7 @@ public class ExecutorsTest extends JSR166TestCase { */ public void testCallableNPE4() { try { - Callable c = Executors.callable((PrivilegedExceptionAction) null); + Callable unused = Executors.callable((PrivilegedExceptionAction) null); shouldThrow(); } catch (NullPointerException success) {} } diff --git a/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java b/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java index 56ffd3c4a7b..09d93a8eecc 100644 --- a/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java +++ b/test/jdk/java/util/concurrent/tck/ForkJoinPoolTest.java @@ -375,7 +375,7 @@ public class ForkJoinPoolTest extends JSR166TestCase { p.shutdown(); assertTrue(p.isShutdown()); try { - ForkJoinTask f = p.submit(new FibTask(8)); + ForkJoinTask unused = p.submit(new FibTask(8)); shouldThrow(); } catch (RejectedExecutionException success) {} } @@ -563,7 +563,7 @@ public class ForkJoinPoolTest extends JSR166TestCase { ExecutorService e = new ForkJoinPool(1); try (PoolCleaner cleaner = cleaner(e)) { try { - Future future = e.submit((Runnable) null); + Future unused = e.submit((Runnable) null); shouldThrow(); } catch (NullPointerException success) {} } @@ -576,7 +576,7 @@ public class ForkJoinPoolTest extends JSR166TestCase { ExecutorService e = new ForkJoinPool(1); try (PoolCleaner cleaner = cleaner(e)) { try { - Future future = e.submit((Callable) null); + Future unused = e.submit((Callable) null); shouldThrow(); } catch (NullPointerException success) {} } diff --git a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java index f10204afa58..ba7b6df82df 100644 --- a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java +++ b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java @@ -1227,8 +1227,9 @@ public class JSR166TestCase extends TestCase { } catch (TimeoutException success) { } catch (Exception fail) { threadUnexpectedException(fail); - } finally { future.cancel(true); } + } assertTrue(millisElapsedSince(startTime) >= timeoutMillis); + assertFalse(future.isDone()); } /** diff --git a/test/jdk/java/util/concurrent/tck/RecursiveTaskTest.java b/test/jdk/java/util/concurrent/tck/RecursiveTaskTest.java index d6dae5ed345..0eb2380be06 100644 --- a/test/jdk/java/util/concurrent/tck/RecursiveTaskTest.java +++ b/test/jdk/java/util/concurrent/tck/RecursiveTaskTest.java @@ -408,7 +408,7 @@ public class RecursiveTaskTest extends JSR166TestCase { FailingFibTask f = new FailingFibTask(8); assertSame(f, f.fork()); try { - Integer r = f.join(); + f.join(); shouldThrow(); } catch (FJException success) { checkCompletedAbnormally(f, success); @@ -427,7 +427,7 @@ public class RecursiveTaskTest extends JSR166TestCase { FailingFibTask f = new FailingFibTask(8); assertSame(f, f.fork()); try { - Integer r = f.get(); + f.get(); shouldThrow(); } catch (ExecutionException success) { Throwable cause = success.getCause(); @@ -448,7 +448,7 @@ public class RecursiveTaskTest extends JSR166TestCase { FailingFibTask f = new FailingFibTask(8); assertSame(f, f.fork()); try { - Integer r = f.get(LONG_DELAY_MS, MILLISECONDS); + f.get(LONG_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (ExecutionException success) { Throwable cause = success.getCause(); @@ -485,7 +485,7 @@ public class RecursiveTaskTest extends JSR166TestCase { FibTask f = new FibTask(8); assertTrue(f.cancel(true)); try { - Integer r = f.invoke(); + f.invoke(); shouldThrow(); } catch (CancellationException success) { checkCancelled(f); @@ -505,7 +505,7 @@ public class RecursiveTaskTest extends JSR166TestCase { assertTrue(f.cancel(true)); assertSame(f, f.fork()); try { - Integer r = f.join(); + f.join(); shouldThrow(); } catch (CancellationException success) { checkCancelled(f); @@ -525,7 +525,7 @@ public class RecursiveTaskTest extends JSR166TestCase { assertTrue(f.cancel(true)); assertSame(f, f.fork()); try { - Integer r = f.get(); + f.get(); shouldThrow(); } catch (CancellationException success) { checkCancelled(f); @@ -545,7 +545,7 @@ public class RecursiveTaskTest extends JSR166TestCase { assertTrue(f.cancel(true)); assertSame(f, f.fork()); try { - Integer r = f.get(LONG_DELAY_MS, MILLISECONDS); + f.get(LONG_DELAY_MS, MILLISECONDS); shouldThrow(); } catch (CancellationException success) { checkCancelled(f); @@ -689,7 +689,7 @@ public class RecursiveTaskTest extends JSR166TestCase { FibTask f = new FibTask(8); f.completeExceptionally(new FJException()); try { - Integer r = f.invoke(); + f.invoke(); shouldThrow(); } catch (FJException success) { checkCompletedAbnormally(f, success); diff --git a/test/jdk/java/util/concurrent/tck/SplittableRandomTest.java b/test/jdk/java/util/concurrent/tck/SplittableRandomTest.java index f9544c9c903..38f4fecefc1 100644 --- a/test/jdk/java/util/concurrent/tck/SplittableRandomTest.java +++ b/test/jdk/java/util/concurrent/tck/SplittableRandomTest.java @@ -39,6 +39,9 @@ import java.util.concurrent.atomic.LongAdder; import java.lang.reflect.Method; import java.util.function.Predicate; import java.util.stream.Collectors; +import java.util.stream.DoubleStream; +import java.util.stream.IntStream; +import java.util.stream.LongStream; import junit.framework.Test; import junit.framework.TestSuite; @@ -357,12 +360,12 @@ public class SplittableRandomTest extends JSR166TestCase { SplittableRandom r = new SplittableRandom(); assertThrows( IllegalArgumentException.class, - () -> { java.util.stream.IntStream x = r.ints(-1L); }, - () -> { java.util.stream.IntStream x = r.ints(-1L, 2, 3); }, - () -> { java.util.stream.LongStream x = r.longs(-1L); }, - () -> { java.util.stream.LongStream x = r.longs(-1L, -1L, 1L); }, - () -> { java.util.stream.DoubleStream x = r.doubles(-1L); }, - () -> { java.util.stream.DoubleStream x = r.doubles(-1L, .5, .6); }); + () -> { IntStream unused = r.ints(-1L); }, + () -> { IntStream unused = r.ints(-1L, 2, 3); }, + () -> { LongStream unused = r.longs(-1L); }, + () -> { LongStream unused = r.longs(-1L, -1L, 1L); }, + () -> { DoubleStream unused = r.doubles(-1L); }, + () -> { DoubleStream unused = r.doubles(-1L, .5, .6); }); } /** @@ -373,12 +376,12 @@ public class SplittableRandomTest extends JSR166TestCase { SplittableRandom r = new SplittableRandom(); assertThrows( IllegalArgumentException.class, - () -> { java.util.stream.IntStream x = r.ints(2, 1); }, - () -> { java.util.stream.IntStream x = r.ints(10, 42, 42); }, - () -> { java.util.stream.LongStream x = r.longs(-1L, -1L); }, - () -> { java.util.stream.LongStream x = r.longs(10, 1L, -2L); }, - () -> { java.util.stream.DoubleStream x = r.doubles(0.0, 0.0); }, - () -> { java.util.stream.DoubleStream x = r.doubles(10, .5, .4); }); + () -> { IntStream unused = r.ints(2, 1); }, + () -> { IntStream unused = r.ints(10, 42, 42); }, + () -> { LongStream unused = r.longs(-1L, -1L); }, + () -> { LongStream unused = r.longs(10, 1L, -2L); }, + () -> { DoubleStream unused = r.doubles(0.0, 0.0); }, + () -> { DoubleStream unused = r.doubles(10, .5, .4); }); } /** diff --git a/test/jdk/java/util/concurrent/tck/StampedLockTest.java b/test/jdk/java/util/concurrent/tck/StampedLockTest.java index a1ef302d998..3ed481122f8 100644 --- a/test/jdk/java/util/concurrent/tck/StampedLockTest.java +++ b/test/jdk/java/util/concurrent/tck/StampedLockTest.java @@ -370,7 +370,7 @@ public class StampedLockTest extends JSR166TestCase { */ public void testInterruptibleOperationsThrowInterruptedExceptionWriteLockedInterrupted() { final StampedLock lock = new StampedLock(); - long s = lock.writeLock(); + long stamp = lock.writeLock(); Action[] interruptibleLockBlockingActions = { () -> lock.writeLockInterruptibly(), @@ -385,6 +385,8 @@ public class StampedLockTest extends JSR166TestCase { shuffle(interruptibleLockBlockingActions); assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions); + + releaseWriteLock(lock, stamp); } /** @@ -392,7 +394,7 @@ public class StampedLockTest extends JSR166TestCase { */ public void testInterruptibleOperationsThrowInterruptedExceptionReadLockedInterrupted() { final StampedLock lock = new StampedLock(); - long s = lock.readLock(); + long stamp = lock.readLock(); Action[] interruptibleLockBlockingActions = { () -> lock.writeLockInterruptibly(), @@ -403,6 +405,8 @@ public class StampedLockTest extends JSR166TestCase { shuffle(interruptibleLockBlockingActions); assertThrowInterruptedExceptionWhenInterrupted(interruptibleLockBlockingActions); + + releaseReadLock(lock, stamp); } /** @@ -726,6 +730,7 @@ public class StampedLockTest extends JSR166TestCase { lock.unlockWrite(s); s = lock.readLock(); assertTrue(lock.toString().contains("Read-locks")); + releaseReadLock(lock, s); } /** diff --git a/test/jdk/java/util/concurrent/tck/SubmissionPublisherTest.java b/test/jdk/java/util/concurrent/tck/SubmissionPublisherTest.java index 2f153ee5d6b..aceafeb155f 100644 --- a/test/jdk/java/util/concurrent/tck/SubmissionPublisherTest.java +++ b/test/jdk/java/util/concurrent/tck/SubmissionPublisherTest.java @@ -985,7 +985,7 @@ public class SubmissionPublisherTest extends JSR166TestCase { public void testConsumeNPE() { SubmissionPublisher p = basicPublisher(); try { - CompletableFuture f = p.consume(null); + CompletableFuture unused = p.consume(null); shouldThrow(); } catch (NullPointerException success) {} } diff --git a/test/jdk/java/util/concurrent/tck/SynchronousQueueTest.java b/test/jdk/java/util/concurrent/tck/SynchronousQueueTest.java index 00f66a29950..4a1d7cbd33c 100644 --- a/test/jdk/java/util/concurrent/tck/SynchronousQueueTest.java +++ b/test/jdk/java/util/concurrent/tck/SynchronousQueueTest.java @@ -464,7 +464,7 @@ public class SynchronousQueueTest extends JSR166TestCase { public void testToArray_null(boolean fair) { final SynchronousQueue q = new SynchronousQueue(fair); try { - Object[] o = q.toArray((Object[])null); + Object[] unused = q.toArray((Object[])null); shouldThrow(); } catch (NullPointerException success) {} } diff --git a/test/jdk/java/util/concurrent/tck/ThreadLocalRandomTest.java b/test/jdk/java/util/concurrent/tck/ThreadLocalRandomTest.java index 0100cf3c8ca..3159dfbaa4a 100644 --- a/test/jdk/java/util/concurrent/tck/ThreadLocalRandomTest.java +++ b/test/jdk/java/util/concurrent/tck/ThreadLocalRandomTest.java @@ -384,27 +384,24 @@ public class ThreadLocalRandomTest extends JSR166TestCase { new AtomicReference<>(); final AtomicLong rand = new AtomicLong(); - long firstRand = 0; - ThreadLocalRandom firstThreadLocalRandom = null; - Runnable getRandomState = new CheckedRunnable() { public void realRun() { ThreadLocalRandom current = ThreadLocalRandom.current(); assertSame(current, ThreadLocalRandom.current()); - // test bug: the following is not guaranteed and not true in JDK8 - // assertNotSame(current, threadLocalRandom.get()); rand.set(current.nextLong()); threadLocalRandom.set(current); }}; - Thread first = newStartedThread(getRandomState); - awaitTermination(first); - firstRand = rand.get(); - firstThreadLocalRandom = threadLocalRandom.get(); + awaitTermination(newStartedThread(getRandomState)); + long firstRand = rand.get(); + ThreadLocalRandom firstThreadLocalRandom = threadLocalRandom.get(); + assertNotNull(firstThreadLocalRandom); for (int i = 0; i < NCALLS; i++) { - Thread t = newStartedThread(getRandomState); - awaitTermination(t); + awaitTermination(newStartedThread(getRandomState)); + if (testImplementationDetails) + // ThreadLocalRandom has been a singleton since jdk8. + assertSame(firstThreadLocalRandom, threadLocalRandom.get()); if (firstRand != rand.get()) return; }