From d3bf00f4cf91c09f863d5690fec40ccfbe5e92cd Mon Sep 17 00:00:00 2001 From: Doug Lea
This interface does not define methods for initially creating, + *
The {@code CompletionStage} interface does not define methods for initially creating, * forcibly completing normally or exceptionally, probing completion * status or results, or awaiting completion of a stage. * Implementations of CompletionStage may provide means of achieving @@ -145,6 +148,12 @@ * enables interoperability among different implementations of this * interface by providing a common conversion type. * + *
Memory consistency effects: Actions in a thread prior to the
+ * submission of a computation producing a {@code CompletionStage}
+ * happen-before that computation begins. And actions taken by
+ * a {@code CompletionStage} happen-before actions of any
+ * dependent stage subsequent to its completion.
+ *
* @param This method is analogous to
@@ -172,9 +181,9 @@ public interface CompletionStage When this stage completes normally, the given function is
- * invoked with this stage's result as the argument, returning
+ * When {@code this} stage completes normally, the given function is
+ * invoked with {@code this} stage's result as the argument, returning
* another CompletionStage. When that stage completes normally,
- * the CompletionStage returned by this method is completed with
+ * the CompletionStage returned is completed with
* the same value.
*
* To ensure progress, the supplied function must arrange
@@ -652,13 +661,13 @@ public CompletionStage When this stage completes normally, the given function is
- * invoked with this stage's result as the argument, returning
+ * When {@code this} stage completes normally, the given function is
+ * invoked with {@code this} stage's result as the argument, returning
* another CompletionStage. When that stage completes normally,
- * the CompletionStage returned by this method is completed with
+ * the CompletionStage returned is completed with
* the same value.
*
* To ensure progress, the supplied function must arrange
@@ -679,10 +688,10 @@ public CompletionStage When this stage completes normally, the given function is
- * invoked with this stage's result as the argument, returning
+ * When {@code this} stage completes normally, the given function is
+ * invoked with {@code this} stage's result as the argument, returning
* another CompletionStage. When that stage completes normally,
- * the CompletionStage returned by this method is completed with
+ * the CompletionStage returned by {@code this} method is completed with
* the same value.
*
* To ensure progress, the supplied function must arrange
@@ -701,13 +710,13 @@ public CompletionStage When this stage is complete, the given function is invoked
+ * When {@code this} stage is complete, the given function is invoked
* with the result (or {@code null} if none) and the exception (or
- * {@code null} if none) of this stage as arguments, and the
+ * {@code null} if none) of {@code this} stage as arguments, and the
* function's result is used to complete the returned stage.
*
* @param fn the function to use to compute the value of the
@@ -719,14 +728,14 @@ public CompletionStage When this stage is complete, the given function is invoked
+ * When {@code this} stage is complete, the given function is invoked
* with the result (or {@code null} if none) and the exception (or
- * {@code null} if none) of this stage as arguments, and the
+ * {@code null} if none) of {@code this} stage as arguments, and the
* function's result is used to complete the returned stage.
*
* @param fn the function to use to compute the value of the
@@ -738,14 +747,14 @@ public CompletionStage When this stage is complete, the given function is invoked
+ * When {@code this} stage is complete, the given function is invoked
* with the result (or {@code null} if none) and the exception (or
- * {@code null} if none) of this stage as arguments, and the
+ * {@code null} if none) of {@code this} stage as arguments, and the
* function's result is used to complete the returned stage.
*
* @param fn the function to use to compute the value of the
@@ -760,22 +769,22 @@ public CompletionStage When this stage is complete, the given action is invoked
+ * When {@code this} stage is complete, the given action is invoked
* with the result (or {@code null} if none) and the exception (or
- * {@code null} if none) of this stage as arguments. The returned
+ * {@code null} if none) of {@code this} stage as arguments. The returned
* stage is completed when the action returns.
*
* Unlike method {@link #handle handle},
- * this method is not designed to translate completion outcomes,
+ * method {@code whenComplete} is not designed to translate completion outcomes,
* so the supplied action should not throw an exception. However,
- * if it does, the following rules apply: if this stage completed
+ * if it does, the following rules apply: if {@code this} stage completed
* normally but the supplied action throws an exception, then the
* returned stage completes exceptionally with the supplied
- * action's exception. Or, if this stage completed exceptionally
+ * action's exception. Or, if {@code this} stage completed exceptionally
* and the supplied action throws an exception, then the returned
- * stage completes exceptionally with this stage's exception.
+ * stage completes exceptionally with {@code this} stage's exception.
*
* @param action the action to perform
* @return the new CompletionStage
@@ -785,23 +794,23 @@ public CompletionStage When this stage is complete, the given action is invoked with the
+ * When {@code this} stage is complete, the given action is invoked with the
* result (or {@code null} if none) and the exception (or {@code null}
- * if none) of this stage as arguments. The returned stage is completed
+ * if none) of {@code this} stage as arguments. The returned stage is completed
* when the action returns.
*
* Unlike method {@link #handleAsync(BiFunction) handleAsync},
- * this method is not designed to translate completion outcomes,
+ * method {@code whenCompleteAsync} is not designed to translate completion outcomes,
* so the supplied action should not throw an exception. However,
- * if it does, the following rules apply: If this stage completed
+ * if it does, the following rules apply: If {@code this} stage completed
* normally but the supplied action throws an exception, then the
* returned stage completes exceptionally with the supplied
- * action's exception. Or, if this stage completed exceptionally
+ * action's exception. Or, if {@code this} stage completed exceptionally
* and the supplied action throws an exception, then the returned
- * stage completes exceptionally with this stage's exception.
+ * stage completes exceptionally with {@code this} stage's exception.
*
* @param action the action to perform
* @return the new CompletionStage
@@ -811,23 +820,23 @@ public CompletionStage When this stage is complete, the given action is invoked with the
+ * When {@code this} stage is complete, the given action is invoked with the
* result (or {@code null} if none) and the exception (or {@code null}
- * if none) of this stage as arguments. The returned stage is completed
+ * if none) of {@code this} stage as arguments. The returned stage is completed
* when the action returns.
*
* Unlike method {@link #handleAsync(BiFunction,Executor) handleAsync},
- * this method is not designed to translate completion outcomes,
+ * method {@code whenCompleteAsync} is not designed to translate completion outcomes,
* so the supplied action should not throw an exception. However,
- * if it does, the following rules apply: If this stage completed
+ * if it does, the following rules apply: If {@code this} stage completed
* normally but the supplied action throws an exception, then the
* returned stage completes exceptionally with the supplied
- * action's exception. Or, if this stage completed exceptionally
+ * action's exception. Or, if {@code this} stage completed exceptionally
* and the supplied action throws an exception, then the returned
- * stage completes exceptionally with this stage's exception.
+ * stage completes exceptionally with {@code this} stage's exception.
*
* @param action the action to perform
* @param executor the executor to use for asynchronous execution
@@ -838,14 +847,14 @@ public CompletionStage The {@code schedule} methods create tasks with various delays
* and return a task object that can be used to cancel or check
- * execution. The {@code scheduleAtFixedRate} and
- * {@code scheduleWithFixedDelay} methods create and execute tasks
- * that run periodically until cancelled.
+ * execution. When delays elapse, tasks are enabled for execution and
+ * behave in accord with other {@link ExecutorService} tasks, except
+ * that {@code scheduleAtFixedRate} and {@code scheduleWithFixedDelay}
+ * methods create and execute tasks that run periodically until
+ * cancelled.
*
* Commands submitted using the {@link Executor#execute(Runnable)}
* and {@link ExecutorService} {@code submit} methods are scheduled
@@ -91,7 +93,7 @@
public interface ScheduledExecutorService extends ExecutorService {
/**
- * Submits a one-shot task that becomes enabled after the given delay.
+ * Submits a one-shot task that becomes enabled for execution after the given delay.
*
* @param command the task to execute
* @param delay the time from now to delay execution
@@ -107,7 +109,7 @@ public ScheduledFuture> schedule(Runnable command,
long delay, TimeUnit unit);
/**
- * Submits a value-returning one-shot task that becomes enabled
+ * Submits a value-returning one-shot task that becomes enabled for execution
* after the given delay.
*
* @param callable the function to execute
@@ -123,7 +125,7 @@ public Delayed tasks execute no sooner than they are enabled, but
+ * Delayed tasks execute no sooner than they are enabled for execution, but
* without any real-time guarantees about when, after they are
* enabled, they will commence. Tasks scheduled for exactly the same
* execution time are enabled in first-in-first-out (FIFO) order of
@@ -568,7 +568,7 @@ public Memory consistency effects: Actions in a thread prior to the
* submission of a computation producing a {@code CompletionStage}
- * happen-before that computation begins. And actions taken by
- * a {@code CompletionStage} happen-before actions of any
- * dependent stage subsequent to its completion.
+ * happen-before that computation begins. And actions taken by
+ * {@code CompletionStage x} happen-before actions of any
+ * dependent stage subsequent to {@code x}'s completion.
*
* @param A {@code CyclicBarrier} supports an optional {@link Runnable} command
* that is run once per barrier point, after the last thread in the party
From c85698c7e8bc73ab8fb9182938d75d6805359b11 Mon Sep 17 00:00:00 2001
From: Doug Lea Acquires the read lock if the write lock is not held by
- * another thread and returns immediately.
+ * any thread and returns immediately.
*
- * If the write lock is held by another thread then
+ * If the write lock is held by any thread then
* the current thread becomes disabled for thread scheduling
* purposes and lies dormant until the read lock has been acquired.
*/
@@ -749,9 +749,9 @@ public void lock() {
* {@linkplain Thread#interrupt interrupted}.
*
* Acquires the read lock if the write lock is not held
- * by another thread and returns immediately.
+ * by any thread and returns immediately.
*
- * If the write lock is held by another thread then the
+ * If the write lock is held by any thread then the
* current thread becomes disabled for thread scheduling
* purposes and lies dormant until one of two things happens:
*
@@ -791,10 +791,10 @@ public void lockInterruptibly() throws InterruptedException {
/**
* Acquires the read lock only if the write lock is not held by
- * another thread at the time of invocation.
+ * any thread at the time of invocation.
*
* Acquires the read lock if the write lock is not held by
- * another thread and returns immediately with the value
+ * any thread and returns immediately with the value
* {@code true}. Even when this lock has been set to use a
* fair ordering policy, a call to {@code tryLock()}
* will immediately acquire the read lock if it is
@@ -806,7 +806,7 @@ public void lockInterruptibly() throws InterruptedException {
* tryLock(0, TimeUnit.SECONDS)} which is almost equivalent
* (it also detects interruption).
*
- * If the write lock is held by another thread then
+ * If the write lock is held by any thread then
* this method will return immediately with the value
* {@code false}.
*
From 93ece642651290a351bcd9be04ef02833493c56a Mon Sep 17 00:00:00 2001
From: Doug Lea Note that the guarantees of the {@code compareAndSet}
* method in this class are weaker than in other atomic classes.
diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
index 1005c122578d7..b31a8edf53a46 100644
--- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
+++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java
@@ -46,10 +46,11 @@
/**
* A reflection-based utility that enables atomic updates to
- * designated non-static {@code volatile long} fields of designated classes.
- * This class is designed for use in atomic data structures in which
- * several fields of the same node are independently subject to atomic
- * updates.
+ * designated non-static {@code volatile long} fields of designated
+ * classes, providing a subset of the functionality of class {@link
+ * VarHandle} that should be used instead. This class is designed for
+ * use in atomic data structures in which several fields of the same
+ * node are independently subject to atomic updates.
*
* Note that the guarantees of the {@code compareAndSet}
* method in this class are weaker than in other atomic classes.
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 a180cc8a1d5ad..00220145d419c 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
@@ -46,11 +46,12 @@
/**
* A reflection-based utility that enables atomic updates to
- * designated non-static {@code volatile} reference fields of designated
- * classes. This class is designed for use in atomic data structures
- * in which several reference fields of the same node are
- * independently subject to atomic updates. For example, a tree node
- * might be declared as
+ * designated non-static {@code volatile} reference fields of
+ * designated classes, providing a subset of the functionality of
+ * class {@link VarHandle} that should be used instead. This class
+ * may be used in atomic data structures in which several reference
+ * fields of the same node are independently subject to atomic
+ * updates. For example, a tree node might be declared as
*
* Note that the guarantees of the {@code compareAndSet}
* method in this class are weaker than in other atomic classes.
* Because this class cannot ensure that all uses of the field
From 044d8dcdd1b29877ce9bf71fbfd4ad5a48e5cc12 Mon Sep 17 00:00:00 2001
From: Doug Lea The {@code schedule} methods create tasks with various delays
- * and return a task object that can be used to cancel or check
+ * and return {@link ScheduledFuture} objects that can be used to cancel or check
* execution. When delays elapse, tasks are enabled for execution and
* behave in accord with other {@link ExecutorService} tasks, except
* that {@code scheduleAtFixedRate} and {@code scheduleWithFixedDelay}
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 52989e8127730..f793d2bcabdf2 100644
--- a/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java
+++ b/src/java.base/share/classes/java/util/concurrent/SubmissionPublisher.java
@@ -604,7 +604,7 @@ public int offer(T item, long timeout, TimeUnit unit,
* Flow.Subscriber#onComplete() onComplete} signals to current
* subscribers, and disallows subsequent attempts to publish. To
* ensure uniform ordering among subscribers, this method may
- * await completion of in-progress offer. Upon return, this
+ * await completion of in-progress offers. Upon return, this
* method does NOT guarantee that all subscribers have
* yet completed.
*/
diff --git a/src/java.base/share/classes/java/util/concurrent/TimeUnit.java b/src/java.base/share/classes/java/util/concurrent/TimeUnit.java
index 34f1577cad23b..d116fb9b22bcc 100644
--- a/src/java.base/share/classes/java/util/concurrent/TimeUnit.java
+++ b/src/java.base/share/classes/java/util/concurrent/TimeUnit.java
@@ -399,7 +399,7 @@ else if (s == MICRO_SCALE)
* @param timeout the maximum time to wait. If less than
* or equal to zero, do not wait at all.
* @throws IllegalMonitorStateException if the current thread is not
- * the owner of this object's monitor.
+ * the owner of the object's monitor.
* @throws InterruptedException if interrupted while waiting
*/
public void timedWait(Object obj, long timeout)
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 00220145d419c..d29c2bac0d0b6 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
@@ -71,19 +71,23 @@
*
* However, it is preferable to use {@link VarHandle}:
* Note that the guarantees of the {@code compareAndSet}
* method in this class are weaker than in other atomic classes.
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 4fce0455b3f78..b5dd95eb9d919 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
@@ -791,7 +791,7 @@ public void lockInterruptibly() throws InterruptedException {
/**
* Acquires the read lock only if the write lock is not held by
- * any thread at the time of invocation.
+ * another thread at the time of invocation.
*
* Acquires the read lock if the write lock is not held by
* any thread and returns immediately with the value
diff --git a/src/java.base/share/classes/java/util/concurrent/package-info.java b/src/java.base/share/classes/java/util/concurrent/package-info.java
index dd0c8f79bc024..f237017799d9f 100644
--- a/src/java.base/share/classes/java/util/concurrent/package-info.java
+++ b/src/java.base/share/classes/java/util/concurrent/package-info.java
@@ -222,7 +222,9 @@
* Method {@code submit} extends base method {@link
* Executor#execute(Runnable)} by creating and returning a {@link Future}
- * that can be used to cancel execution and/or wait for completion.
+ * that can be used to cancel execution and/or wait for completion;
+ * also reporting exceptions that would otherwise be uncaught
+ * using method {@code execute}.
* Methods {@code invokeAny} and {@code invokeAll} perform the most
* commonly useful forms of bulk execution, executing a collection of
* tasks and then waiting for at least one, or all, to
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 d29c2bac0d0b6..e3ca4830d5a21 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
@@ -87,7 +87,7 @@
* RIGHT = l.findVarHandle(Node.class, "right", Node.class);
* } catch (ReflectiveOperationException e) {
* throw new ExceptionInInitializerError(e);
- * }}} Note that the guarantees of the {@code compareAndSet}
* method in this class are weaker than in other atomic classes.
{@code
* class OneShotPublisher implements Publisher
+ * }}}}
*
*
Date: Wed, 18 Jun 2025 13:37:01 -0400
Subject: [PATCH 03/12] Revert
---
.../java/util/concurrent/Exchanger.java | 84 +++++++++++--------
1 file changed, 47 insertions(+), 37 deletions(-)
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 e41f8c051a853..75de69b3e5283 100644
--- a/src/java.base/share/classes/java/util/concurrent/Exchanger.java
+++ b/src/java.base/share/classes/java/util/concurrent/Exchanger.java
@@ -276,10 +276,10 @@ static final class Node {
int index; // Arena index
Object item; // This thread's current item
volatile Object match; // Item provided by releasing thread
- final Thread thread;
+ volatile Thread parked; // Set to this thread when parked, else null
Node() {
index = -1; // initialize on first use
- seed = (thread = Thread.currentThread()).threadId();
+ seed = Thread.currentThread().threadId();
}
}
@@ -329,10 +329,10 @@ private final V xchg(V x, long deadline)
Participant ps = participant;
Object item = (x == null) ? ps : x; // translate nulls
Node p = ps.get();
- p.item = item;
int i = p.index; // if < 0, move
int misses = 0; // ++ on collide, -- on spinout
- Object v; // the match
+ Object offered = null; // for cleanup
+ Object v = null;
outer: for (;;) {
int b, m; Slot s; Node q;
if ((m = (b = bound) & MMASK) == 0) // volatile read
@@ -344,10 +344,11 @@ private final V xchg(V x, long deadline)
}
else if ((q = s.entry) != null) { // try release
if (ENTRY.compareAndSet(s, q, null)) {
+ Thread w;
v = q.item;
q.match = item;
- if (i == 0)
- LockSupport.unpark(q.thread);
+ if (i == 0 && (w = q.parked) != null)
+ LockSupport.unpark(w);
break;
}
else { // collision
@@ -365,39 +366,47 @@ else if ((nb = (b + 1) & MMASK) < alen) {
}
}
}
- else if (ENTRY.compareAndSet(s, null, p)) { // try offer
- boolean tryCancel = false;
- for (long ns = 1L;;) {
- if (p.match == null && !tryCancel) {
- if ((deadline != 0L &&
- (ns = deadline - System.nanoTime()) <= 0L) ||
- Thread.currentThread().isInterrupted())
- tryCancel = true; // cancel unless match
- else if (ncpu > 1 &&
- (i != 0 || // check for busy VTs
- (!ForkJoinWorkerThread.hasKnownQueuedWork()))) {
- for (int j = SPINS; p.match == null && j > 0; --j)
- Thread.onSpinWait();
+ else { // try offer
+ if (offered == null)
+ offered = p.item = item;
+ if (ENTRY.compareAndSet(s, null, p)) {
+ boolean tryCancel; // true if interrupted
+ Thread t = Thread.currentThread();
+ if (!(tryCancel = t.isInterrupted()) && ncpu > 1 &&
+ (i != 0 || // check for busy VTs
+ (!ForkJoinWorkerThread.hasKnownQueuedWork()))) {
+ for (int j = SPINS; j > 0; --j) {
+ if ((v = p.match) != null) {
+ MATCH.set(p, null);
+ break outer; // spin wait
+ }
+ Thread.onSpinWait();
}
}
- if ((v = MATCH.getAndSet(p, null)) != null)
- break outer;
- else if (!tryCancel && i == 0) {
- if (deadline == 0L)
- LockSupport.park(this);
- else
- LockSupport.parkNanos(this, ns);
- }
- else if (ENTRY.compareAndSet(s, p, null)) { // cancel
- boolean interrupted = Thread.interrupted();
- if (interrupted || ns <= 0L) {
- p.item = null;
- if (interrupted)
+ for (long ns = 1L;;) { // block or cancel offer
+ if ((v = p.match) != null) {
+ MATCH.set(p, null);
+ break outer;
+ }
+ if (i == 0 && !tryCancel &&
+ (deadline == 0L ||
+ ((ns = deadline - System.nanoTime()) > 0L))) {
+ p.parked = t; // emable unpark and recheck
+ if (p.match == null) {
+ if (deadline == 0L)
+ LockSupport.park(this);
+ else
+ LockSupport.parkNanos(this, ns);
+ tryCancel = t.isInterrupted();
+ }
+ p.parked = null;
+ }
+ else if (ENTRY.compareAndSet(s, p, null)) { // cancel
+ offered = p.item = null;
+ if (Thread.interrupted())
throw new InterruptedException();
- else
+ if (deadline != 0L && ns <= 0L)
throw new TimeoutException();
- }
- else {
i = -1; // move and restart
if (bound != b)
misses = 0; // stale
@@ -407,13 +416,14 @@ else if ((b & MMASK) != 0) {
misses = 0; // try to shrink
BOUND.compareAndSet(this, b, b - 1 + SEQ);
}
- break;
+ continue outer;
}
}
}
}
}
- p.item = null; // cleanup
+ if (offered != null) // cleanup
+ p.item = null;
@SuppressWarnings("unchecked") V ret = (v == participant) ? null : (V)v;
return ret;
}
From cadb2c91f6bd33d13a615d73b0f6af32450dbd0f Mon Sep 17 00:00:00 2001
From: Doug Lea
Date: Thu, 19 Jun 2025 07:03:39 -0400
Subject: [PATCH 04/12] Address review comments
---
.../classes/java/util/concurrent/CompletionStage.java | 10 +++++-----
.../share/classes/java/util/concurrent/Flow.java | 2 +-
.../classes/java/util/concurrent/ForkJoinPool.java | 2 +-
.../concurrent/atomic/AtomicIntegerFieldUpdater.java | 2 +-
.../util/concurrent/atomic/AtomicLongFieldUpdater.java | 2 +-
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/java.base/share/classes/java/util/concurrent/CompletionStage.java b/src/java.base/share/classes/java/util/concurrent/CompletionStage.java
index 0dc320aeee08a..2299046a6b174 100644
--- a/src/java.base/share/classes/java/util/concurrent/CompletionStage.java
+++ b/src/java.base/share/classes/java/util/concurrent/CompletionStage.java
@@ -99,8 +99,8 @@
* requiring its completion complete exceptionally as well, with a
* {@link CompletionException} holding the exception as its
* cause. This distinguishes exceptions in an action itself from those
- * it depends on. If you want them handled in the same way, you might
- * choose to catch {@link RuntimeException}. If a stage is dependent
+ * it depends on. If they are to be handled in the same way, instead
+ * catch {@link RuntimeException}. If a stage is dependent
* on both of two stages, and both complete exceptionally,
* then the CompletionException may correspond to either one of these
* exceptions. If a stage is dependent on either of two
@@ -150,9 +150,9 @@
*
*
{@code
* class OneShotPublisher implements Publisher
*
*
Date: Thu, 19 Jun 2025 07:25:35 -0400
Subject: [PATCH 05/12] Add JDK-8353155 doc improvement
---
.../share/classes/java/util/concurrent/RunnableFuture.java | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/java.base/share/classes/java/util/concurrent/RunnableFuture.java b/src/java.base/share/classes/java/util/concurrent/RunnableFuture.java
index b6b088ae7cd82..8585cfe108297 100644
--- a/src/java.base/share/classes/java/util/concurrent/RunnableFuture.java
+++ b/src/java.base/share/classes/java/util/concurrent/RunnableFuture.java
@@ -47,8 +47,9 @@
*/
public interface RunnableFuture
Date: Thu, 19 Jun 2025 07:39:06 -0400
Subject: [PATCH 06/12] Add JDK-8186959 docfix
---
.../share/classes/java/util/concurrent/Executors.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/java.base/share/classes/java/util/concurrent/Executors.java b/src/java.base/share/classes/java/util/concurrent/Executors.java
index ba7c2e1efeebe..ef3d634801090 100644
--- a/src/java.base/share/classes/java/util/concurrent/Executors.java
+++ b/src/java.base/share/classes/java/util/concurrent/Executors.java
@@ -306,7 +306,7 @@ public static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFa
}
/**
- * Creates a thread pool that can schedule commands to run after a
+ * Creates a fixed-size thread pool that can schedule commands to run after a
* given delay, or to execute periodically.
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle
@@ -318,7 +318,7 @@ public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
}
/**
- * Creates a thread pool that can schedule commands to run after a
+ * Creates a fixed-size thread pool that can schedule commands to run after a
* given delay, or to execute periodically.
* @param corePoolSize the number of threads to keep in the pool,
* even if they are idle
From 4ef7649af4f35fdfa8d2cc918a3d1b7c1ff95cbc Mon Sep 17 00:00:00 2001
From: Doug Lea
Date: Thu, 19 Jun 2025 07:54:13 -0400
Subject: [PATCH 07/12] Add JDK-8190889 docfix
---
src/java.base/share/classes/java/util/concurrent/TimeUnit.java | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/java.base/share/classes/java/util/concurrent/TimeUnit.java b/src/java.base/share/classes/java/util/concurrent/TimeUnit.java
index f02aa9f593192..34f1577cad23b 100644
--- a/src/java.base/share/classes/java/util/concurrent/TimeUnit.java
+++ b/src/java.base/share/classes/java/util/concurrent/TimeUnit.java
@@ -398,6 +398,8 @@ else if (s == MICRO_SCALE)
* @param obj the object to wait on
* @param timeout the maximum time to wait. If less than
* or equal to zero, do not wait at all.
+ * @throws IllegalMonitorStateException if the current thread is not
+ * the owner of this object's monitor.
* @throws InterruptedException if interrupted while waiting
*/
public void timedWait(Object obj, long timeout)
From b10114e59e5b4b6ef3e6d789ea1f831a7568f3c1 Mon Sep 17 00:00:00 2001
From: Doug Lea
Date: Thu, 19 Jun 2025 13:23:34 -0400
Subject: [PATCH 08/12] Add JDK-6317534 and JDK-6351533 doc improvements
---
.../share/classes/java/util/concurrent/CyclicBarrier.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
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 87e498d9c247a..ca78c25462487 100644
--- a/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java
+++ b/src/java.base/share/classes/java/util/concurrent/CyclicBarrier.java
@@ -44,7 +44,10 @@
* useful in programs involving a fixed sized party of threads that
* must occasionally wait for each other. The barrier is called
* cyclic because it can be re-used after the waiting threads
- * are released.
+ * are released. If you need support for variable numbers of parties
+ * per cycle, alternate actions on exceptions, termination control,
+ * contention control, or status monitoring, use the more flexible
+ * {@link Phaser} class.
*
*
Date: Thu, 19 Jun 2025 14:24:40 -0400
Subject: [PATCH 09/12] Add JDK-8195628 doc fix
---
.../concurrent/locks/ReentrantReadWriteLock.java | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
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 3e0b293380f5f..4fce0455b3f78 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
@@ -734,9 +734,9 @@ protected ReadLock(ReentrantReadWriteLock lock) {
* Acquires the read lock.
*
*
Date: Thu, 19 Jun 2025 18:42:58 -0400
Subject: [PATCH 10/12] Adding JDK-8333172 to doc improvements
---
.../atomic/AtomicIntegerFieldUpdater.java | 9 ++++---
.../atomic/AtomicLongFieldUpdater.java | 9 ++++---
.../atomic/AtomicReferenceFieldUpdater.java | 27 +++++++++++++++----
3 files changed, 32 insertions(+), 13 deletions(-)
diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
index 469b5bdba8c1e..f947eb4f7db88 100644
--- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
+++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java
@@ -46,10 +46,11 @@
/**
* A reflection-based utility that enables atomic updates to
- * designated non-static {@code volatile int} fields of designated classes.
- * This class is designed for use in atomic data structures in which
- * several fields of the same node are independently subject to atomic
- * updates.
+ * designated non-static {@code volatile int} fields of designated
+ * classes, providing a subset of the functionality of class {@link
+ * VarHandle} that should be used instead. This class is designed for
+ * use in atomic data structures in which several fields of the same
+ * node are independently subject to atomic updates.
*
*
{@code
* class Node {
@@ -68,6 +69,22 @@
* // ... and so on
* }}
*
+ * However, it is preferable to use {@link VarHandle}:
+ * {@code
+ * class Node {
+ * private volatile Node left, right;
+ *
+ * private static final VarHandle LEFT = MethodHandles.lookup().
+ * findVarHandle(Node.class, "left", Node.class);
+ * private static final VarHandle RIGHT = MethodHandles.lookup().
+ * findVarHandle(Node.class, "right", Node.class);
+ * Node getLeft() { return left; }
+ * boolean compareAndSetLeft(Node expect, Node update) {
+ * return LEFT.compareAndSet(this, expect, update);
+ * }
+ * // ... and so on
+ * }}
+ *
*
Date: Fri, 20 Jun 2025 09:56:12 -0400
Subject: [PATCH 11/12] Address review comments; add JDK-6374942
---
.../concurrent/ScheduledExecutorService.java | 2 +-
.../util/concurrent/SubmissionPublisher.java | 2 +-
.../java/util/concurrent/TimeUnit.java | 2 +-
.../atomic/AtomicReferenceFieldUpdater.java | 28 +++++++++++--------
.../locks/ReentrantReadWriteLock.java | 2 +-
.../java/util/concurrent/package-info.java | 4 ++-
6 files changed, 23 insertions(+), 17 deletions(-)
diff --git a/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java b/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java
index 4fa9d00660bb0..034d98687c257 100644
--- a/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java
+++ b/src/java.base/share/classes/java/util/concurrent/ScheduledExecutorService.java
@@ -40,7 +40,7 @@
* delay, or to execute periodically.
*
*
{@code
+ * import java.lang.invoke.VarHandle;
+ * import java.lang.invoke.MethodHandles;
* class Node {
- * private volatile Node left, right;
- *
- * private static final VarHandle LEFT = MethodHandles.lookup().
- * findVarHandle(Node.class, "left", Node.class);
- * private static final VarHandle RIGHT = MethodHandles.lookup().
- * findVarHandle(Node.class, "right", Node.class);
- * Node getLeft() { return left; }
- * boolean compareAndSetLeft(Node expect, Node update) {
- * return LEFT.compareAndSet(this, expect, update);
- * }
- * // ... and so on
- * }}
+ * private volatile Node left, right;
+ * private static final VarHandle LEFT, RIGHT;
+ * Node getLeft() { return left; }
+ * boolean compareAndSetLeft(Node expect, Node update) {
+ * return LEFT.compareAndSet(this, expect, update);
+ * }
+ * // ... and so on
+ * static { try {
+ * MethodHandles.Lookup l = MethodHandles.lookup();
+ * LEFT = l.findVarHandle(Node.class, "left", Node.class);
+ * RIGHT = l.findVarHandle(Node.class, "right", Node.class);
+ * } catch (ReflectiveOperationException e) {
+ * throw new ExceptionInInitializerError(e);
+ * }}}Memory Consistency Properties
*
From 26d96b88e3ce8fe1143ecfc3f5a781e4dd4a6985 Mon Sep 17 00:00:00 2001
From: Doug Lea
Date: Fri, 20 Jun 2025 11:48:53 -0400
Subject: [PATCH 12/12] Fix ARFU type; add JDK-7176957
---
.../share/classes/java/util/concurrent/ExecutorService.java | 4 +++-
.../util/concurrent/atomic/AtomicReferenceFieldUpdater.java | 2 +-
2 files changed, 4 insertions(+), 2 deletions(-)
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 0d4acf8913e04..f899b56b28883 100644
--- a/src/java.base/share/classes/java/util/concurrent/ExecutorService.java
+++ b/src/java.base/share/classes/java/util/concurrent/ExecutorService.java
@@ -56,7 +56,9 @@
*
*