diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java index c50621090bb..9a18002ebd5 100644 --- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java +++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java @@ -1156,7 +1156,9 @@ public abstract class AbstractQueuedLongSynchronizer */ private boolean canReacquire(ConditionNode node) { // check links, not status to avoid enqueue race - return node != null && node.prev != null && isEnqueued(node); + Node p; // traverse unless known to be bidirectionally linked + return node != null && (p = node.prev) != null && + (p.next == node || isEnqueued(node)); } /** 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 921150f58ca..618ba7b05f3 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 @@ -1524,7 +1524,9 @@ public abstract class AbstractQueuedSynchronizer */ private boolean canReacquire(ConditionNode node) { // check links, not status to avoid enqueue race - return node != null && node.prev != null && isEnqueued(node); + Node p; // traverse unless known to be bidirectionally linked + return node != null && (p = node.prev) != null && + (p.next == node || isEnqueued(node)); } /**