Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concurrent read-only HashMap

I am writing a web-service that heavily relies on a single large Map that is completely updated once every hour. The rest of the time many threads concurrently read the table.

My question is: What is the most efficient construct to realize such a Map?

The Map can be rather larger (100 - 500 MB). There is only read access except once an hour where the whole map is replaced.

I was thinking about just using a Java HashMap and maybe using reflection to set the field final between the updates if this improves performance, but I have no clue how to make the JVM optimize for many concurrent reads.

like image 665
xgb84j Avatar asked Feb 06 '14 23:02

xgb84j


2 Answers

Since the map isn't updated while being used, use a HashMap, which gives excellent O(1) lookup performance (at the sacrifice of thread safety).

When it's time to refresh, build a new map and swap references.

Consider using an AtomicReference to make the swap thread safe:

private final AtomicReference<Map<K, V>> mapRef = new AtomicReference<>();

To use:

mapRef.get().get(key);

To initialize or swap in a new map:

Map<K, V> newMap = new HashMap<>();
// populate map
mapRef.set(newMap); // all threads will see this change
like image 74
Bohemian Avatar answered Oct 04 '22 20:10

Bohemian


Go for ConcurrentHashMap. It allows Concurrent read access without compromising on performance.

like image 35
Keyur Avatar answered Oct 04 '22 21:10

Keyur