java - 可重入锁实现细节

标签 java multithreading concurrency reentrantlock java-15

我试图理解 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,对吗?

我认为这是一次潜在的重试,因为在调用 initialTryLocktryAcquire 之间,锁可能已被释放。这样做的好处可能是,因为下一个操作(在 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/

相关文章:

java - Android Thread 并发运行的线程之间通知

Java 线程计数不起作用

java - 在 tomcat 5 上部署 war 提示文件是目录

java - TicTacToe 游戏的 OutOfBoundsException;问题: arrays?

c - 在 C 语言的 Ubuntu 上,多个线程不能同时工作

java - 如何在java中正确测试多线程/并发方法?

c++ - 用于 Sutter 的无锁队列的 Boost 库或 C++0x 原子的等效实现?

java - 从 ExecutorService 访问队列 (LinkedBlockingQueue) 的正确方法

javascript - Java 8 更新 91 问题

java - 如何使用 logback 以 csv 格式写入日志文件?