< prev index next >

src/java.base/share/classes/java/util/concurrent/locks/ReentrantLock.java

Print this page
8229442: AQS and lock classes refresh
Reviewed-by: martin

*** 117,159 **** */ abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -5179523762034025860L; /** ! * Performs non-fair tryLock. tryAcquire is implemented in ! * subclasses, but both need nonfair try for trylock method. */ @ReservedStackAccess ! final boolean nonfairTryAcquire(int acquires) { ! final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { ! if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } ! } ! else if (current == getExclusiveOwnerThread()) { ! int nextc = c + acquires; ! if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); ! setState(nextc); return true; } return false; } @ReservedStackAccess protected final boolean tryRelease(int releases) { int c = getState() - releases; ! if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); ! boolean free = false; ! if (c == 0) { ! free = true; setExclusiveOwnerThread(null); - } setState(c); return free; } protected final boolean isHeldExclusively() { --- 117,183 ---- */ abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -5179523762034025860L; /** ! * Performs non-fair tryLock. */ @ReservedStackAccess ! final boolean tryLock() { ! Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { ! if (compareAndSetState(0, 1)) { setExclusiveOwnerThread(current); return true; } ! } else if (getExclusiveOwnerThread() == current) { ! if (++c < 0) // overflow throw new Error("Maximum lock count exceeded"); ! setState(c); return true; } return false; } + /** + * Checks for reentrancy and acquires if lock immediately + * available under fair vs nonfair rules. Locking methods + * perform initialTryLock check before relaying to + * corresponding AQS acquire methods. + */ + abstract boolean initialTryLock(); + + @ReservedStackAccess + final void lock() { + if (!initialTryLock()) + acquire(1); + } + + @ReservedStackAccess + final void lockInterruptibly() throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + if (!initialTryLock()) + acquireInterruptibly(1); + } + + @ReservedStackAccess + final boolean tryLockNanos(long nanos) throws InterruptedException { + if (Thread.interrupted()) + throw new InterruptedException(); + return initialTryLock() || tryAcquireNanos(1, nanos); + } + @ReservedStackAccess protected final boolean tryRelease(int releases) { int c = getState() - releases; ! if (getExclusiveOwnerThread() != Thread.currentThread()) throw new IllegalMonitorStateException(); ! boolean free = (c == 0); ! if (free) setExclusiveOwnerThread(null); setState(c); return free; } protected final boolean isHeldExclusively() {
*** 193,232 **** /** * Sync object for non-fair locks */ static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; protected final boolean tryAcquire(int acquires) { ! return nonfairTryAcquire(acquires); } } /** * Sync object for fair locks */ static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; /** ! * Fair version of tryAcquire. Don't grant access unless ! * recursive call or no waiters or is first. */ ! @ReservedStackAccess ! protected final boolean tryAcquire(int acquires) { ! final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { ! if (!hasQueuedPredecessors() && ! compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } ! } ! else if (current == getExclusiveOwnerThread()) { ! int nextc = c + acquires; ! if (nextc < 0) throw new Error("Maximum lock count exceeded"); ! setState(nextc); return true; } return false; } } --- 217,287 ---- /** * Sync object for non-fair locks */ static final class NonfairSync extends Sync { private static final long serialVersionUID = 7316153563782823691L; + + final boolean initialTryLock() { + Thread current = Thread.currentThread(); + if (compareAndSetState(0, 1)) { // first attempt is unguarded + setExclusiveOwnerThread(current); + return true; + } else if (getExclusiveOwnerThread() == current) { + int c = getState() + 1; + if (c < 0) // overflow + throw new Error("Maximum lock count exceeded"); + setState(c); + return true; + } else + return false; + } + + /** + * Acquire for non-reentrant cases after initialTryLock prescreen + */ protected final boolean tryAcquire(int acquires) { ! if (getState() == 0 && compareAndSetState(0, acquires)) { ! setExclusiveOwnerThread(Thread.currentThread()); ! return true; ! } ! return false; } } /** * Sync object for fair locks */ static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; + /** ! * Acquires only if reentrant or queue is empty. */ ! final boolean initialTryLock() { ! Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { ! if (!hasQueuedThreads() && compareAndSetState(0, 1)) { setExclusiveOwnerThread(current); return true; } ! } else if (getExclusiveOwnerThread() == current) { ! if (++c < 0) // overflow throw new Error("Maximum lock count exceeded"); ! setState(c); ! return true; ! } ! return false; ! } ! ! /** ! * Acquires only if thread is first waiter or empty ! */ ! protected final boolean tryAcquire(int acquires) { ! if (getState() == 0 && !hasQueuedPredecessors() && ! compareAndSetState(0, acquires)) { ! setExclusiveOwnerThread(Thread.currentThread()); return true; } return false; } }
*** 262,272 **** * current thread becomes disabled for thread scheduling * purposes and lies dormant until the lock has been acquired, * at which time the lock hold count is set to one. */ public void lock() { ! sync.acquire(1); } /** * Acquires the lock unless the current thread is * {@linkplain Thread#interrupt interrupted}. --- 317,327 ---- * current thread becomes disabled for thread scheduling * purposes and lies dormant until the lock has been acquired, * at which time the lock hold count is set to one. */ public void lock() { ! sync.lock(); } /** * Acquires the lock unless the current thread is * {@linkplain Thread#interrupt interrupted}.
*** 312,322 **** * interrupt over normal or reentrant acquisition of the lock. * * @throws InterruptedException if the current thread is interrupted */ public void lockInterruptibly() throws InterruptedException { ! sync.acquireInterruptibly(1); } /** * Acquires the lock only if it is not held by another thread at the time * of invocation. --- 367,377 ---- * interrupt over normal or reentrant acquisition of the lock. * * @throws InterruptedException if the current thread is interrupted */ public void lockInterruptibly() throws InterruptedException { ! sync.lockInterruptibly(); } /** * Acquires the lock only if it is not held by another thread at the time * of invocation.
*** 342,352 **** * @return {@code true} if the lock was free and was acquired by the * current thread, or the lock was already held by the current * thread; and {@code false} otherwise */ public boolean tryLock() { ! return sync.nonfairTryAcquire(1); } /** * Acquires the lock if it is not held by another thread within the given * waiting time and the current thread has not been --- 397,407 ---- * @return {@code true} if the lock was free and was acquired by the * current thread, or the lock was already held by the current * thread; and {@code false} otherwise */ public boolean tryLock() { ! return sync.tryLock(); } /** * Acquires the lock if it is not held by another thread within the given * waiting time and the current thread has not been
*** 419,429 **** * @throws InterruptedException if the current thread is interrupted * @throws NullPointerException if the time unit is null */ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { ! return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } /** * Attempts to release this lock. * --- 474,484 ---- * @throws InterruptedException if the current thread is interrupted * @throws NullPointerException if the time unit is null */ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { ! return sync.tryLockNanos(unit.toNanos(timeout)); } /** * Attempts to release this lock. *
< prev index next >