我正在尝试理解ReentrantLock::lock方法中的一个特定细节。我看着它,把它看作是:
final void lock() {
if (!initialTryLock()) {
acquire(1);
}
}首先,它尝试这个方法:initialTryLock (我将在NonfairSync中查看),它执行以下操作:
compareAndSwap(0, 1),意思是如果没有人持有锁(0),我可以抓住它(1),我现在就持有锁。如果上面的锁失败,它检查请求锁的线程是否已经是所有者。false,这意味着我无法获得锁。H 214f 215让我们假设上面的失败。然后继续并调用acquire in AbstractQueuedSynchronizer
public final void acquire(int arg) {
if (!tryAcquire(arg))
acquire(null, arg, false, false, false, 0L);
}它首先在tryAcquire中调用NonfairSync
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之后)失败,是这个线程的昂贵的队列。因此,我想这是有意义的(重试)因为这一点?
发布于 2021-01-31 01:26:42
只是为了添加到the answer above。
tryAcquire可能会简单地返回false,对吗?
不是的。
这一实施:
boolean tryAcquire(int acquires) {
return false;
}会破坏AbstractQueuedSynchronizer的工作。
原因是tryAcquire()是在AbstractQueuedSynchronizer中获取锁的唯一方法。
甚至是acquire() in the end uses tryAcquire()。
因此,如果tryAcquire()总是返回false,那么acquire()就永远不会获得锁。
当多个线程争用锁时,将使用acquire()。
发布于 2021-01-30 04:14:13
initialTryLock()包含重入性functionality:- javadoc: /\*\* \* 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();- source code in `NonfairSync`: 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; }在这里:
-第一个if检查锁是否被取走(如果锁是空的,则取锁)
-第二个if检查所获取的锁是否属于当前线程--这是重入逻辑。
tryAcquire()必须由任何扩展AbstractQueuedSynchronizer的类实现。
- what the method must do is described in its javadoc in `AbstractQueuedSynchronizer`/** *尝试在独占模式下获取。此方法应查询*对象的状态是否允许在*排他模式下获取它,如果允许,则查询对象的状态是否允许获取它。*. */受保护的布尔tryAcquire(int arg) {抛出新的UnsupportedOperationException();}
- implementation in `NonfairSync` does exactly that (and doesn't contain reentrancy functionality):在setExclusiveOwnerThread(Thread.currentThread());预屏幕*/受保护的最终布尔值tryAcquire(int获取){ if (getState() == 0&compareAndSetState(获取)){ initialTryLock返回真;}返回false;}之后,为不可重入的情况获取
https://stackoverflow.com/questions/65928109
复制相似问题