Home > Software design >  How to prevent threads from reading inconsistent data from ConcurrentHashMap?
How to prevent threads from reading inconsistent data from ConcurrentHashMap?

Time:01-19

I'm using a ConcurrentHashMap<String, String> that works as a cache, and where read operations are performed to validate if an element is already in the cache and write operations to add an element to the cache.

So, my question is: what are the best practices to always read the most recent ConcorrentHashMap values?

I want to ensure data consistency and not have cases like:

  1. With the map.get("key") method, the first thread validates that this key does not yet exist in the map, then it does the map.put("value")
  2. The second thread reads the data before the first thread puts the element on the map, leading to inconsistent data.

Code example:

Optional<String> cacheValue = Optional.ofNullable(cachedMap.get("key"));

if (cacheValue.isPresent()) {
    // Perform actions

} else {
    cachedMap.putIfAbsent("key", "value");
    // Perform actions
}

How can I ensure that my ConcurrentHashMap is synchronized and doesn't retrieve inconsistent data?

Should I perform these map operations inside a synchronized block?

CodePudding user response:

You probably need to do it this way:

if (cachedMap.putIfAbsent("key", "value") == null) {
    // Perform actions "IS NOT PRESENT" 
} else {
    // Perform actions "IS PRESENT"
}

Doing it in two checks is obviously not atomic, so if you're having problems with the wrong values getting put in the cache, then that's likely your problem.

CodePudding user response:

what are the best practices to always read the most recent ConcurrentHashMap values?

Oracle's Javadoc for ConcurrentHashMap says, "Retrievals reflect the results of the most recently completed update operations holding upon their onset." In other words, any time you call map.get(...) or any other method on the map, you are always working with the "most recent" content.

*BUT*

Is that enough? Maybe not. If your program threads expect any kind of consistency between two or more keys in the map, or if your threads expect any kind of consistency between something that is stored in the map and something that is stored elsewhere, then you are going to need to provide some explicit higher-level synchronization between the threads.

I can't provide an example that would be specific to the problem that's puzzling you because your question doesn't really say what that problem is.

  •  Tags:  
  • Related