Yesterday, I noticed that one of our systems was using a Lock where a plain old synchronized() block would suffice, and I thought to myself, does this matter? Since the Lock was already fulfilling the same role, the only real question was performance.
My gut told me that there should be a performance difference between a built-in language construct and a library, but experience has taught me not to guess when it comes to performance. A quick Google search led to a lot of posts deflecting the main question with cries of “premature optimization!”, and thus did not help me at all.
I ended up writing a micro-benchmark program (code on GitHub) that exercises Lock and synchronized() equally to measure total throughput. I measured two different situations, single-threaded and two-threaded, because of previous reading that indicated the JVM was pretty good at optimizing the uncontended case.
The results were clear and fairly unsurprising: synchronized() is substantially faster. In the single-threaded test, synchronized() was about 7.5x faster on average than Lock.lock(). In the two-threaded test, synchronized() was still the clear winner, about 2x faster on average.
Bottom line: if you can use synchronized() instead of Lock, then you definitely should use synchronized().