【发布时间】:2021-05-01 19:36:04
【问题描述】:
我试图了解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 之后)失败,是该线程的昂贵入队。所以我想这是有道理的(重试)因为那个?
【问题讨论】:
-
你说的是哪个版本的java src?
-
@Andrea 我的错,我在看 jdk-15;如果这很重要。
-
在java 12 ReentrantLock::lock 直接调用sync.acquire(1) 并且函数initialTryLock 不存在。所以你提到的代码是最近介绍的。如果有人要调查,他应该参考正确的java版本
-
@Andrea 好点。我添加了正确的标签。谢谢
标签: java multithreading concurrency reentrantlock java-15