Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
226 views
in Technique[技术] by (71.8m points)

java - Reentrant lock implementation detail

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Just to add to the answer above.

tryAcquire could have simply returned false, right?

No.

This implementation:

boolean tryAcquire(int acquires) {
  return false;
}

would break the work of AbstractQueuedSynchronizer.

The reason is that tryAcquire() is the only way to take the lock in AbstractQueuedSynchronizer.

Even acquire() in the end uses tryAcquire().

So if tryAcquire() always returned false then acquire() would never acquire the lock.

And acquire() is used when several threads contend for the lock.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...