【问题标题】:ReentrantLock in Java Flight RecorderJava Flight Recorder 中的 ReentrantLock
【发布时间】:2021-06-20 11:00:21
【问题描述】:

ReentrantLock 使用什么样的机制?我试图了解它会在 Java Flight Recording 下显示的位置。我的预期是锁会在 Java Monitor Wait 部分下,但事实并非如此。

背景:
我正在尝试通过捕获 java 飞行记录来调试有问题的 ReentrantLock。锁本身很简单:

public class SomeClass {
  private final ReentrantLock lock = new ReentrantLock();
  
  public void capture() {
    boolean exclusive = someFunction();
    try {
      if (exclusive) {
        lock.lock();
      }  

      // critical code 

    } finally {
      if (exclusive) {
        lock.unlock();  
      }
    }
  }
}

在我的实验中,我的应用程序应该调用 capture 函数 200 万次,在某些情况下,锁会根据 someFunction() 被激活。由于没有得到预期的结果,我将函数硬编码为始终为真,但在我的记录中没有观察到 200 万个 Java Monitor Waiting 事件。

Zulu Mission Control screenshot

【问题讨论】:

  • if (exclusive { lock.lock(); } 如果块缺少括号,可能是问题
  • @sanjeevRm 这只是为了说明锁的工作原理而编写的快速 sudo 代码。我已经更新了代码。

标签: java debugging locking jfr


【解决方案1】:

ReentrantLocks 不使用 Java 内部监视器。通过synchronized 关键字进行同步和Locks 是不同的概念。另请参阅this 相关答案。

通过synchronized 同步(= 内部监视器/锁的使用)将锁信息直接存储在对象的内部内存表示中,并在本机代码中实现。锁将锁信息存储在自己的 Java 对象中,并在 Java 代码中实现。有了它,锁比内置的内在监视器更灵活。例如,它们允许在对象边界上互斥,它们可以授予多个线程并发读取访问权限,并让开发人员在公平或不公平锁定之间进行选择。内置同步无法实现的所有功能。

因此,尽管 ReentrantLock(如 JavaDoc 中所述)与使用 synchronized 方法和语句访问的隐式监视器锁具有相同的基本行为和语义,但它以完全不同的方式实现。

获得灵活性是以复杂性为代价的。虽然跟踪内部监视器的状态非常简单,但监视和检测甚至分析 ReentrantLocks 的死锁要困难得多。据我所知,与内置锁/监视器相比,大多数监控工具(包括飞行记录器)不提供或仅提供有限的锁支持。

您将体会到内置同步机制的简单性,这是您第一次必须分析大量使用 ReentrantLocks 或其他锁实现的生产代码中的死锁 ;-)

【讨论】:

    【解决方案2】:

    有为 java.util.concurrent 添加事件的增强请求,但如果不增加开销则很难做到。

    https://bugs.openjdk.java.net/browse/JDK-8067779

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-27
      • 2021-04-11
      • 2022-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-27
      • 1970-01-01
      相关资源
      最近更新 更多