Micro-benchmarks of some concurrency features in Java 8, 11, 17 and 21

Mitsunori Komatsu
2 min readFeb 23, 2024

--

There are various concurrency features in Java. I sometimes observed a lock class had a good performance in a Java version while it had a poor performance in another Java version when I did micro-benchmarks. So, I wanted to know which concurrency control had a better performance in each Java version.

I created https://github.com/komamitsu/java-lock-bench to satisfy my curiosity. It contains these 2 types of micro-benchmarks:

Counter

  • 100%: increment (read-modify-write) operation
  • I usually used java.util.concurrent.atomic.AtomicLong for this kind of operation. But it’s a really good choice?

Map

  • 20%: Read-modify-write operation
  • 80%: Read-only operation
  • I usually used java.util.concurrent.ConcurrentHashMap for this kind of operation. But it’s a really good choice?

See https://github.com/komamitsu/java-lock-bench?tab=readme-ov-file#what-types-of-benchmarks for details

I executed those benchmarks on Linux instances of GitHub Actions using Java 8, 11, 17 and 21. The results are as follows:

Counter

  • java.util.concurrent.locks.StampedLock maintained strong performance across all the Java versions
  • synchronized keyword (intrinsic lock) generally exhibited a poor performance, except in Java 17

Map

  • java.util.concurrent.locks.StampedLock maintained good performance across all the Java versions
  • java.util.concurrent.locks.ReentrantReadWriteLock basically showed a poor performance in all the Java versions java.util.concurrent.locks.ReentrantLock was rather better than it
  • java.util.concurrent.ConcurrentHashMap didn’t perform so well
  • The errors of the benchmarks for synchronized keyword (intrinsic lock) were basically large. But maybe the performance was good.

This post doesn’t look into the reasons behind the performance differences. But I’ll investigate them when I have time later.

--

--