I am trying to understand a particular detail in ReentrantLock::lock
method. I am looking at it and seeing it as:
final void lock() {
if (!initialTryLock()) {
acquire(1);
}
}
So first it tries this method : initialTryLock
(I will look in NonfairSync
), which does this:
- it does a
compareAndSwap(0, 1)
, meaning if no one holds the lock (0
) and I can grab it (1
), I hold the lock now.
- if the above fails, it checks if the thread requesting the lock is the owner already.
- if that fails it returns
false
, meaning I could not acquire the lock.
Let's assume the above failed. It then goes on and calls acquire
in AbstractQueuedSynchronizer
:
public final void acquire(int arg) {
if (!tryAcquire(arg))
acquire(null, arg, false, false, false, 0L);
}
It calls tryAcquire
first in NonfairSync
:
protected final boolean tryAcquire(int acquires) {
if (getState() == 0 && compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
You can see that it tries to acquire the lock again, though the initialTryLock
already failed. In theory, this tryAcquire
could have simply returned false
, right?
I see this as a potential retry, because between the calls of initialTryLock
and tryAcquire
, the lock might have been released. The benefit of this might be that because the next operation (after tryAcquire
) fails, is the expensive enqueue of this thread. So I guess this makes sense (to retry) because of that?
question from:
https://stackoverflow.com/questions/65928109/reentrant-lock-implementation-detail 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…