我试图理解 ReentrantLock::lock
方法中的特定细节。我看着它并将其视为:
final void lock() {
if (!initialTryLock()) {
acquire(1);
}
}
所以首先它尝试这个方法:initialTryLock
(我将查看NonfairSync
),它的作用是:
- 它执行
compareAndSwap(0, 1)
,这意味着如果没有人持有锁 (0
),我就可以捕获它 (1
) >),我现在持有锁。 - 如果上述失败,它会检查请求锁的线程是否已经是所有者。
- 如果失败,它将返回
false
,这意味着我无法获取锁。
假设上面的操作失败了。然后继续调用 AbstractQueuedSynchronizer
中的 acquire
:
public final void acquire(int arg) {
if (!tryAcquire(arg))
acquire(null, arg, false, false, false, 0L);
}
它首先在 NonfairSync
中调用 tryAcquire
:
protected final boolean tryAcquire(int acquires) {
if (getState() == 0 && compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(Thread.currentThread());
return true;
}
return false;
}
您可以看到它再次尝试获取锁,尽管initialTryLock
已经失败。理论上,这个 tryAcquire
可能只是返回 false
,对吗?
我认为这是一次潜在的重试,因为在调用 initialTryLock
和 tryAcquire
之间,锁可能已被释放。这样做的好处可能是,因为下一个操作(在 tryAcquire
之后)失败,因此该线程的排队成本很高。所以我想这(重试)是有意义的吗?
最佳答案
只是添加到the answer above .
tryAcquire
could have simply returned false, right?
没有。
这个实现:
boolean tryAcquire(int acquires) {
return false;
}
会破坏AbstractQueuedSynchronizer
的工作。
原因是 tryAcquire()
是在 AbstractQueuedSynchronizer
中获取锁定的唯一方法。
偶数acquire()
in the end uses tryAcquire()
.
因此,如果 tryAcquire()
始终返回 false
,则 acquire()
将永远不会获取锁。
当多个线程争用锁时,会使用acquire()
。
关于java - 可重入锁实现细节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65928109/