gpt4 book ai didi

java - notifyAll() 分析时的调用差异数

转载 作者:搜寻专家 更新时间:2023-10-30 21:33:14 26 4
gpt4 key购买 nike

我已经使用 JVMTI 实现了一个简单的分析器来显示对 wait()notifyAll() 的调用。作为测试用例,我正在使用。 producer consumer example of Oracle .我有以下三个事件:

  • 调用 notifyAll()
  • wait() 被调用
  • wait() 剩下

wait() 调用及其离开时使用事件 MonitorEnterMonitorExit 进行分析。当退出名为 notifyAll 的方法时,分析 notifyAll() 调用。

现在我有以下结果,第一个来自分析器本身,第二个来自 Java,我在其中放置了适当的 System.out .println 语句。

    // Profiler:
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 left wait()
Thread-1 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 left wait()
Thread-1 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 left wait()
Thread-1 invoked notifyAll()

// Java:
Thread-0 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 invoked notifyAll()
Thread-0 invoked notifyAll()
Thread-1 invoked wait()
Thread-1 invoked notifyAll()

有没有人解释这种差异的来源? notifyAll() 被调用了很多次。有人告诉我这可能是由于 Java 对操作系统的请求的误报响应。

它向操作系统发送了一个 notifyAll() 请求并发送了一个误报响应,看起来请求成功了。由于 notifyAll 是通过分析方法调用而不是 MonitorEnter 记录的,它可以解释为什么等待时不会发生这种情况。

我忘了说,我没有单独运行程序,两个日志来自同一次执行。

附加信息

最初作为答案添加,由 extraneon 移至问题:

我想我发现了一些额外的 notifyAll 来自哪里,我添加了调用 notifyAll 的方法上下文的分析:

723519: Thread-1 invoked notifyAll() in Consumer.take
3763279: Thread-0 invoked notifyAll() in Producer.put
4799016: Thread-0 invoked notifyAll() in Producer.put
6744322: Thread-0 invoked notifyAll() in Producer.put
8450221: Thread-0 invoked notifyAll() in Producer.put
10108959: Thread-0 invoked notifyAll() in Producer.put
39278140: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
40725024: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
42003869: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
58448450: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
60236308: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
61601587: Thread-1 invoked notifyAll() in java.util.ResourceBundle.endLoading
70489811: Thread-1 invoked notifyAll() in Consumer.take
75068409: Thread-1 invoked wait() in Drop.take
75726202: Thread-1 left wait() in Drop.take
77035733: Thread-1 invoked notifyAll() in Consumer.take
81264978: Thread-1 invoked notifyAll() in Consumer.take
85810491: Thread-1 invoked wait() in Drop.take
86477385: Thread-1 left wait() in Drop.take
87775126: Thread-1 invoked notifyAll() in Consumer.take

但即使没有这些外部调用,也有很多 notifyAll 调用没有出现在 printf 调试中。

最佳答案

我花了一些时间分析 Producer-Consumer Oracle 提供的示例和您的输出(探查器和 Java 程序)。除了几个意想不到的 notifyAll() 之外,您的输出中还有一些奇怪的东西:

  1. 我们应该期望 wait() 方法执行 4 次(生产者操作的 String 数组有 4 个元素)。你的探查器的结果表明它只执行了三遍。

  2. 另一件非常奇怪的事情是探查器输出中的线程编号。该示例有两个线程,但是您的探查器在一个线程中执行所有代码,即 Thread-1,而 Thread-0 仅执行 notifyAll().

  3. 提供的示例代码从并发的角度和语言的角度正确编程:wait()notifyAll() 在同步方法中以确保控制显示器;等待条件在 while 循环中,通知正确地放置在方法的末尾。但是,我注意到 catch (InterruptedException e) block 是空的,这意味着如果正在等待的线程被中断,将执行 notifyAll() 方法。这可能是几个意外 notifyAll() 的原因。

总而言之,如果不对代码进行一些修改,不进行一些额外的测试,就很难找出问题出在哪里。

作为旁注,我将保留此链接 Creating a Debugging and Profiling Agent with JVMTI对于那些想玩 JVMTI 的好奇者。

关于java - notifyAll() 分析时的调用差异数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5868999/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com