Why do Java's synchronized Collections not use Read/Write locks?

collections, concurrency, java

Solution

Read-write locks are part of performance optimization, which means it can allow greater concurrency in certain situations. The necessary condition is, that they are applied on data structures which are read most of the time, but not modified.

Under other conditions they perform slightly worse than exclusive locks, which comes natural since they have a greater complexity.

It is most efficient, if the locks of a read-write lock are held typically for a moderately long time and only few modifications on the guarded resources.

Hence, whether read-write locks are better than exclusive locks depends on the use case. Eventually you have to measure with profiling which locks perform better.

Taking this into account it seems fitting to choose an exclusive lock for `Collections.synchronizedMap` addressing the general use case instead of the special case with mostly-readers.

Further Links

- Starvation with ReadWriteLocks

Refactoring Java Programs for Flexible Locking

They wrote a tool which converts locks in a Java application automatically into `ReentrantLocks` and `ReadWriteLocks` where appropriate. For measuring purposes they have also provided some interesting benchmarking results:

[...] However, in a configuration where write operations were more prevalent, the version with synchronized blocks was 50% faster than one based on read-write locks with the Sun 1.6.0_07 JVM (14% faster with the Sun 1.5.0_15 JVM).

In a low-contention case with just 1 reader and 1 writer, the performance differences were less extreme, and each of the three types of locks yielded the fastest version on at least one machine/VM configuration (e.g., note that ReentrantLocks were fastest on the 2-core machine with the Sun 1.5.0_15 JVM).

Problem

After stuff like `Hashtable` and `Vector` where discouraged, and when the Collections synchronized wrappers came up, I thought synchronization would be handled more efficiently. Now that I looked into the code, I'm surprised that it really is just wrapping the collections with synchronization blocks. Why are `ReadWriteLock`s not included into, for example, SynchronizedMap in Collections? Is there some efficiency consideration that doesn't make it worth it?

Original source