|
|
|
Back to newsletter 301 contents
Can you have a concurrency bug in totally thread-safe code? Take a moment to think about it. This simple thread-safe class gives you one kind of answer: class Multiply {volatile int x,y; void x(int i){x=i;} void y(int i){y=i;} int calc(){return x*y;}}. If "m" is a "Multiply" instance, I can run m.x(3);m.y(4);print(m.calc()) and see a value other than 12 printed! This is a concurrency bug. This class is technically thread-safe in that you always see the result of the latest operations on it, but logically not thread-safe because different threads can overwrite the value "x" and "y" resulting in an unexpected value from "calc". Even making the "calc" method synchronized, or having an atomic "xy(int, int)" wouldn't change that, the issue is that all three operations need to be atomically together for correctness. So depending on how you interpret "thread-safety", this could be considered thread-safe code that has a concurrency bug.
It's a trivial example, but consider full applications which have many classes and code running in parallel. This trivial example shows that thread-safety is not a simple matter of making things volatile or synchronized or wrapped in locks. The atomicity of updates and accesses to related fields matters a lot. This was exactly the challenge I had to address in my article Finding the root cause of a rarely occurring race condition where I needed to find a concurrency bug using only code analysis in a situation where it was impossible to reproduce the concurrency bug in a debuggable way - as is often the case in production systems. I use a generic approach to this kind of problem, making it a useful read for anyone encountering this situation.
Now on to all the usual newsletter list of links, tips, tools, news and talks, and as usual I've extracted all the tips into this month's tips page.
Java performance tuning related news
Java performance tuning related tools
Back to newsletter 301 contents