Strange ConcurrentHashMap behaviour

38 views Asked by At

We have a high throughput application that stores cached values in the ConcurrentHashMap that is updated and read from quite regularly. Possibly updated 100's of times per second.

Take the example below:

Map<Long, Object> map= new ConcurrentHashMap<>();

......

public void updateValue(Long key, Object value) {
    map.put(key, value);
}

public Object readValue(Long key) {
    return map.get(key);
}

......

Object val = readValue(key); //Works the majority of the time but can return null even though previous calls returned a value
if (val == null) {
    val = readValue(key); // This works
}    

Very often a call to readValue will result in null being returned, but immediately calling it again will return the correct Object. To me this makes no sense. My assumption is the concurrent call to put and get at the same time is causing the issue, but how can this be the case? We are not doing any removes so that rules out a missing entry. It's completely sporadic and I can't get to the bottom of it.

Any thoughts would be appreciated.

1

There are 1 answers

0
Basil Bourque On

You said:

My assumption is the concurrent call to put and get at the same time is causing the issue, but how can this be the case?

So you are making calls to put and get on separate threads in rapid succession?

If so, the put-operation may not have completed while the thread of the get-operation is scheduled for execution.

To quote the Javadoc for ConcurrentHashMap:

Retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove). Retrievals reflect the results of the most recently completed update operations holding upon their onset.

Even though you may think your get-operation is happening after your put-operation, you cannot know that for certain when operating across threads. Actual execution order across threads at runtime is unpredictable.