java - 如何使用 StampedLock 乐观锁定?(我无法理解 java 文档中的代码示例)

标签 java multithreading concurrency locking stampedlock

最近我了解到存在StampedLock ?

https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/locks/StampedLock.html 我意识到它改进了 ReentrantReadWriteLock,但有一些不同:

  • 不可重入
  • 支持光锁
  • 支持从readLock升级到writeLock

我也阅读了示例 frpm javadoc 但我不理解该代码:

class Point {
  private double x, y;
  private final StampedLock sl = new StampedLock();
  // a read-only method
  // upgrade from optimistic read to read lock
  double distanceFromOrigin() {
    long stamp = sl.tryOptimisticRead();
    try {
      retryHoldingLock: for (;; stamp = sl.readLock()) {
        if (stamp == 0L)
          continue retryHoldingLock;
        // possibly racy reads
        double currentX = x;
        double currentY = y;
        if (!sl.validate(stamp))
          continue retryHoldingLock;
        return Math.hypot(currentX, currentY);
      }
    } finally {
      if (StampedLock.isReadLockStamp(stamp))
        sl.unlockRead(stamp);
    }
  }
}

possibly racy reads 是什么意思? [在评论中回答]

如果另一个线程读取 xy 是否有问题? [在评论中回答]

为什么在tryOptimisticRead失败时先执行tryOptimisticRead,然后在for循环中执行readLock?什么逻辑?

为什么我们有 if (StampedLock.isReadLockStamp(stamp)) finally block vbefore unlock 中?

最佳答案

why do we execute tryOptimisticRead first and readLock in the for loop in case of tryOptimisticRead failure? what the logic?

最好的情况是我们能够读取 xy 而无需获取锁。这并不意味着我们不建立事前发生的关系,它只是意味着我们不需要调用可能的阻塞操作。

tryOptimisticRead 返回给我们一个标记值。这种对内部状态的 volatile 读取确定了在对该标记值进行 volatile 写入之前写入的任何内容在后续读取之后都是可见的。这意味着,如果在 tryOptimisticRead 中返回的标记值在您读取 xy 时没有改变,则不会发生另一次写入,我们具有最新的值。但是,如果标记值确实发生变化,则所有赌注都将取消,您需要保护自己,如下所述。

根据您的用例,xy 有可能在您执行 distanceFromOrigin 的过程中的某个时间点发生变化>。如果 xy 发生变化,并且可能经常发生变化,那么您将希望最终取得成功。

readLock 是程序说“好吧,我放弃,让我们以阻塞方式读取它”的方式。理论上,您可以在最终调用 readLock 之前将代码写入 tryOptimisticRead 几次,但您会想要给自己一个机会,以防 x y 不断更新。

Why do we have if (StampedLock.isReadLockStamp(stamp)) inside finally block vbefore unlock ?

如果 readLock 被调用,您必须在退出前释放它,以便后续的 writeLock 可以获得锁。如果您在 tryOptimisticRead 中成功,您将不必释放 readLock,因为您从一开始就不需要获取它。

关于java - 如何使用 StampedLock 乐观锁定?(我无法理解 java 文档中的代码示例),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55766479/

相关文章:

Java Swing 一个 JCheckBox 上有两个 Action 监听器

C++ thread assignment throwing SIGSEGV 收藏

java - 自动滚动 ListView?

Java泛型选择性返回值

java - 在 TextView 中将 StringBuilder 变量转换为 html

java - Spring Integration 和 Transaction Management——需要多难?

java - 为什么这个多线程程序输出 100 而不是预期的 200?

java - 如果其他类更改了某些内容,如何使更改对一个类可见?

java - 如何用java开发类似生产者消费者的应用?

java - 使用多线程递增/递减/打印(代码审查)