< 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 >