首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重入锁实现细节

重入锁实现细节
EN

Stack Overflow用户
提问于 2021-01-27 22:06:33
回答 2查看 280关注 0票数 2

我正在尝试理解ReentrantLock::lock方法中的一个特定细节。我看着它,把它看作是:

代码语言:javascript
复制
final void lock() {
   if (!initialTryLock()) {
       acquire(1);
   }
}

首先,它尝试这个方法:initialTryLock (我将在NonfairSync中查看),它执行以下操作:

  • 它做一个compareAndSwap(0, 1),意思是如果没有人持有锁(0),我可以抓住它(1),我现在就持有锁。如果上面的锁失败,它检查请求锁的线程是否已经是所有者。
  • 如果失败,返回false,这意味着我无法获得锁。H 214f 215

让我们假设上面的失败。然后继续并调用acquire in AbstractQueuedSynchronizer

代码语言:javascript
复制
public final void acquire(int arg) {
    if (!tryAcquire(arg))
        acquire(null, arg, false, false, false, 0L);
}

它首先在tryAcquire中调用NonfairSync

代码语言:javascript
复制
protected final boolean tryAcquire(int acquires) {
    if (getState() == 0 && compareAndSetState(0, acquires)) {
        setExclusiveOwnerThread(Thread.currentThread());
        return true;
    }
    return false;
}

您可以看到它再次尝试获取锁,尽管initialTryLock已经失败。理论上,这个tryAcquire可以简单地返回false,对吗?

我认为这是一次潜在的重试,因为在initialTryLocktryAcquire调用之间,锁可能已经释放。这样做的好处可能是,因为下一个操作(在tryAcquire之后)失败,是这个线程的昂贵的队列。因此,我想这是有意义的(重试)因为这一点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-31 01:26:42

只是为了添加到the answer above

tryAcquire可能会简单地返回false,对吗?

不是的。

这一实施:

代码语言:javascript
复制
boolean tryAcquire(int acquires) {
  return false;
}

会破坏AbstractQueuedSynchronizer的工作。

原因是tryAcquire()是在AbstractQueuedSynchronizer中获取锁的唯一方法。

甚至是acquire() in the end uses tryAcquire()

因此,如果tryAcquire()总是返回false,那么acquire()就永远不会获得锁。

当多个线程争用锁时,将使用acquire()

票数 2
EN

Stack Overflow用户

发布于 2021-01-30 04:14:13

  • initialTryLock()包含重入性functionality:

代码语言:javascript
复制
- 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();
代码语言:javascript
复制
- 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

的类实现。

代码语言:javascript
复制
- what the method must do is described in its javadoc in `AbstractQueuedSynchronizer`

/** *尝试在独占模式下获取。此方法应查询*对象的状态是否允许在*排他模式下获取它,如果允许,则查询对象的状态是否允许获取它。*. */受保护的布尔tryAcquire(int arg) {抛出新的UnsupportedOperationException();}

代码语言:javascript
复制
- implementation in `NonfairSync` does exactly that (and doesn't contain reentrancy functionality):

在setExclusiveOwnerThread(Thread.currentThread());预屏幕*/受保护的最终布尔值tryAcquire(int获取){ if (getState() == 0&compareAndSetState(获取)){ initialTryLock返回真;}返回false;}之后,为不可重入的情况获取

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65928109

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档