diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 56c52fb4ffa..bb969b5d2bd 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -2852,22 +2852,20 @@ private final void unlockRoot() { * Possibly blocks awaiting root lock. */ private final void contendedLock() { - boolean waiting = false; + Thread current = Thread.currentThread(), w; for (int s;;) { if (((s = lockState) & ~WAITER) == 0) { if (U.compareAndSetInt(this, LOCKSTATE, s, WRITER)) { - if (waiting) - waiter = null; + if (waiter == current) + U.compareAndSetObject(this, WAITERTHREAD, current, null); return; } } - else if ((s & WAITER) == 0) { - if (U.compareAndSetInt(this, LOCKSTATE, s, s | WAITER)) { - waiting = true; - waiter = Thread.currentThread(); - } - } - else if (waiting) + else if ((s & WAITER) == 0) + U.compareAndSetInt(this, LOCKSTATE, s, s | WAITER); + else if ((w = waiter) == null) + U.compareAndSetObject(this, WAITERTHREAD, null, current); + else if (w == current) LockSupport.park(this); } } @@ -3287,6 +3285,8 @@ static boolean checkInvariants(TreeNode t) { private static final Unsafe U = Unsafe.getUnsafe(); private static final long LOCKSTATE = U.objectFieldOffset(TreeBin.class, "lockState"); + private static final long WAITERTHREAD + = U.objectFieldOffset(TreeBin.class, "waiter"); } /* ----------------Table Traversal -------------- */