We have a single thread that regularly updates a Map. And then we have multiple other threads that read this map.
This is how the update thread executes
private Map<String, SecondMap> firstMap = new ConcurrentHashMap<>();
private void refresh() //This method is called every X seconds by one thread only
{
   List<SecondMap> newData = getLatestData();
   final List<String> newEntries = new ArrayList<>(); 
   for(SecondMap map : newData) {
       newEntries.add(map.getName());
       firstMap.put(map.getName(), map); 
   }
   final Set<String> cachedEntries = firstMap.keySet();
   for (final String cachedEntry : cachedEntries) {
       if (!newEntries.contains(cachedEntry)) {
           firstMap.remove(cachedEntry);
       }
   } 
}
public Map<String, SecondMap> getFirstMap()//Other threads call this
{
    return firstMap;
}
The SecondMap class looks like this
class SecondMap {
    Map<String, SomeClass> data; //Not necessarily a concurrent hashmap
    public Map<String, SomeClass> getData() {
        return data;
    }
}
Below is the simplified version of how reader threads access
public void getValue() {
    Map<String, SecondMap> firstMap = getFirstMap();
    SecondMap secondMap = firstMap.get("SomeKey");
    secondMap.getData().get("AnotherKey");// This returns null
}
We are seeing that in other threads, when they iterate over the received 
firstMap, sometimes they get null values for some keys in the SecondMap. We don't see any null values for keys in the firstMap, but we see null values for keys in second value. One thing that we can rule out is that the method getLatestData will never return such data. It reads from a database and returns these entries. There can never be null values in the database in the first place. Also we see that this happens occasionally. We are probably missing something here in handling multi-threaded situation in a proper way, but I am looking for an explanation why this can happen.
 
    