Java 中同步顺序的断言
在高度并发的系统中,很难确信您对锁的使用是正确的。具体来说,如果在另一个线程中以正确的顺序获取锁时未按预期的顺序获取锁,则可能会导致死锁。
有一些工具(例如 Coverity)可以对代码库进行静态分析并查找“不寻常”的锁定顺序。我想探索其他选择来满足我的需求。
是否有任何轻量级*工具用于检测 Java 代码,可以检测以非预期顺序获取锁的情况?我可以通过注释/注释明确调用锁定命令。
首选免费和/或开源解决方案。如果有非仪器方法可以解决此问题,也请发表评论。
* 就我的目的而言,轻量级意味着...
- 如果是仪器,我仍然可以以相同的大概性能运行我的程序。我认为 30-50% 的退化是可以接受的。
- 我不必花半天时间与该工具交互只是为了得到一个“好的”结果。理想情况下,我应该只在出现问题时才注意到我正在使用它。
- 如果是仪器,那么在生产环境中应该很容易禁用它。
- 它不应该在每个
synchronize
语句中使我的代码变得混乱。如前所述,我可以明确地注释/注释通过相对顺序锁定的对象或对象类。
In highly concurrent systems, it can be difficult to be confident that your usage of locks is correct. Specifically, deadlocks can result if locks are acquired in an order that was not expected while being acquired in the proper order in another thread.
There are tools (e.g. Coverity) which can do static analysis on a code base and look for "unusual" locking orders. I'd like to explore other options to meet my needs.
Are there any light-weight* tools for instrumenting Java code which can detect cases where locks are being acquired in an order other than expected? I am okay with explicitly calling out locking orders via comments / annotations.
Free and/or open-source solutions preferred. Please also comment if there are non-instrumentation approaches to this problem.
* For my purposes, light-weight means...
- If it is instrumentation, I can still run my program with the same ballpark performance. 30-50% degradation is acceptable, I suppose.
- I don't have to spend half the day interacting with the tool just to get an "okay" out of it. Ideally I should only notice that I'm using it when there's a problem.
- If it is instrumentation, it should be easy to disable for production environments.
- It shouldn't clutter my code at every
synchronize
statement. As previously mentioned, I'm okay with explicitly commenting/annotating the objects or classes of objects which get locked with relative orderings.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以使用 AspectJ,它相对容易学习,并且允许您设置自己的监控线程及其访问的任何锁的定制和简化方式。
You can use AspectJ, which is relatively easy to learn and will allow you to setup your own customized and simplified way of monitoring your threads and any locks they access.
虽然无法让您一路顺利,但一个好的开始是使用 JCIP 注释,以及 FindBugs 捕获了一些内容。
Doesn't get you all the way there, but a good start is to use the JCIP annotations, and FindBugs catches a few things.
我没有使用过 AspectJ,所以不能保证它的易用性。我使用 ASM 创建自定义代码分析器,这大约花了 2 天的时间。仪器同步的工作应该是类似的。一旦您熟悉了方面,AspectJ 应该会更快、更容易。
我已经为基于 C++ 的服务器实现了死锁检测跟踪。我是这样做的:
Lock A 列表 ->锁B-> Lock C
生成对(Lock A, Lock B), (Lock A, Lock C), (Lock B, Lock C)
我在好几天都找不到死锁的原因后才这样做,又花了几天的时间来实施,又花了几个小时才找到死锁。
如果您正在考虑在 Java 中使用这种方法,需要考虑的是:
synchronized
来保护您的关键部分?您使用的是 java.lang.concurrent 中的类吗? (这些可能需要特殊处理/检测)__FILE__
和__LINE__
。 ASM 将为您提供类名、方法名和签名。I have not used AspectJ so cannot vouch for how easy it is to use. I have used ASM to create a custom code profiler, this was about 2 days work. The effort to instrument synchronization should be similar. AspectJ should be quicker and easier once you are up to speed with aspects.
I have implemented deadlock detecting trace for our c++ based server. Here is how I did it:
<time> <tid> <lockid> <acquiring|releasing> <location in code>
Lock A -> Lock B -> Lock C
generate the pairs(Lock A, Lock B), (Lock A, Lock C), (Lock B, Lock C)
I did this after failing to find the cause of a deadlock for a number of days, it took a few more days to implement and a few hours to find the deadlock.
If you are considering this approach in Java things to consider are:
synchronized
to protect your critical sections? Are you using the classes in java.lang.concurrent? (these might require special handling/instrumentation)__FILE__
and__LINE__
in c++. ASM will give you the class name, method name and signature.