After blogging about how Micro-Benchmarks are often misleading and focused on proving a point, I went ahead and wrote a little micro-benchmark to curb my curiosity. What I wanted to know is this:
In the face of massive contention, how do the following compare to each other:
- Synchronized Block
- Unfair ReentrantLock
- Fair ReentrantLock
- An Atomic Object
To do this test I wrote 3 different implementations that all did that same thing:
- Increment a long (or AtomicLong)
The results are not at all surprising, an atomic structure comes out much faster than the others, while Fair Locks are by far the slowest. Now I already said that Micro Benchmarks are misleading, so why write this? The fact is that most systems have very low contention ratios. The interesting thing about a contention is that: the more threads trying to access a resource, the worse the bottle-neck becomes. A locked structure must always enter and exit the lock, even when there is no contention. An atomic structure will never have to enter a lock, but may have to spin a few times. If you are concerned about atomic starvation (spinning forever), you can put a limit on how many times your code is willing to spin, and then enter a lock (this is in fact how a Java monitor works).
In short: make sure you really know your contention ratio before writing loads of complex code. You may find that in a continuously high load system, an unfair lock (or synchronized block) is the best way to go.