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...
synchronize
statement. As previously mentioned, I'm okay with explicitly commenting/annotating the objects or classes of objects which get locked with relative orderings.Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods.
Synchronized access means it is thread-safe. So different threads can access the collection concurrently without any problems, but it is probably a little bit slower depending on what you are doing. Unsynchronized is the opposite. Not thread-safe, but a little bit faster. Follow this answer to receive notifications.
Class Level lock can be achieved by using two keywords static and synchronized in any method signature.
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.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With