gpt4 book ai didi

java - 断言Java中的同步顺序

转载 作者:搜寻专家 更新时间:2023-10-30 19:46:54 24 4
gpt4 key购买 nike

在高度并发的系统中,很难确信您对锁的使用是正确的。具体来说,如果在另一个线程中以正确的顺序获取锁时,以非预期的顺序获取锁,则可能会导致死锁。

有些工具(例如 Coverity)可以对代码库进行静态分析并查找“异常”锁定顺序。我想探索其他选项来满足我的需求。

是否有用于检测 Java 代码的任何轻量级*工具,可以检测以非预期顺序获取锁的情况?我可以通过评论/注释明确调用锁定命令。

首选免费和/或开源解决方案。如果有解决此问题的非仪器化方法,也请发表评论。

* 就我而言,轻量级意味着......

  • 如果是检测,我仍然可以以相同的大致性能运行我的程序。我想 30-50% 的退化是可以接受的。
  • 我不必花半天时间与该工具进行交互,只是为了得到一个“好的”结果。理想情况下,我应该只在出现问题时才注意到我在使用它。
  • 如果是工具,应该很容易在生产环境中禁用它。
  • 它不应该在每个 synchronize 语句中打乱我的代码。如前所述,我可以明确注释/注释使用相对顺序锁定的对象或对象类。

最佳答案

我没有使用过 AspectJ,所以不能保证它的易用性。我用过ASM创建自定义代码分析器,这大约需要 2 天的时间。仪器同步的工作应该是相似的。一旦您跟上了方面的速度,AspectJ 应该会更快更容易。

我已经为我们基于 c++ 的服务器实现了死锁检测跟踪。这是我的做法:

  • 每当获取或释放锁时,我都会跟踪:
    • <time> <tid> <lockid> <acquiring|releasing> <location in code>
  • 这个额外的跟踪非常显着地影响了性能并且在生产中不可用。
  • 因此,当在生产中发现可能的死锁时,我使用日志文件来弄清楚死锁周围发生了什么。然后在我的跟踪打开的情况下在测试环境中重现此功能。
  • 然后我在日志文件上运行一个脚本来查看是否可能出现死锁以及如何出现死锁。我使用了一个 awk 脚本,使用了这个算法:
    • 每行
      • 如果收购
        • 将 lockid 添加到该线程的当前锁列表
        • 将此列表中的每对锁添加到此线程的一组锁对中。例如 Lock A -> Lock B -> Lock C 的列表生成对 (Lock A, Lock B), (Lock A, Lock C), (Lock B, Lock C)
      • 如果释放
        • 从该线程列表的尾部删除当前的 lockid
    • 对于每个锁对,在所有其他线程中搜索反向锁对,每个匹配项都是潜在的死锁,因此打印受影响的对和线程
    • 我没有让算法变得更智能,而是检查了锁获取以查看它是否是真正的死锁。

我在几天没有找到死锁的原因之后才这样做,又花了几天时间来实现,几个小时才找到死锁。

如果您在 Java 中考虑这种方法,需要考虑的是:

  • 你只用synchronized吗保护你的关键部分?您使用的是 java.lang.concurrent 中的类吗? (这些可能需要特殊处理/仪器)
  • 使用 aspects/ASM 打印代码位置有多容易?我用了__FILE____LINE__在 C++ 中。 ASM 会给你类名、方法名和签名。
  • 您无法检测用于保护您的跟踪/日志记录的锁。
  • 如果对文件对象使用每个线程的日志文件和线程本地存储,则可以简化检测。
  • 您如何唯一标识要同步的对象?也许 toString() 和 System.identityHashCode() 就足够了,但可能需要更多。我在 C++ 中使用了对象的地址。

关于java - 断言Java中的同步顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4046910/

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