Java Performance: synchronized() vs Lock

Engineering

Learn from our challenges and triumphs as our talented engineering team offers insights for discussion and sharing.

Java Performance: synchronized() vs Lock

Engineering

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().