The best theory I can offer is that the writer threads are still writing into the original map for a short time after the change is made. This could especially happen if perAccountMap_
is not volatile as the change made by the copyAndClear
method would not be seen by the other threads immediately.
Synchronized and unsynchronized writers to HashMap - results not as expected
-
29-09-2022 - |
Question
I have come across code that does not properly synchronize access to a Map - however I analyzed the impact of the non-synchronized code and it is not as I expected.
Essentially the code has multiple writer threads that write to a HashMap perAccountMap_ this code is correctly synchronized.
However there is a section of code called by a separate thread which reads the Map and resets it:
// Unsynchronized code :( - called from a single thread - reads Map and resets it
public static Map<PDKey, PData> copyAndClearPerAccountMap()
{
Map<PDKey, PData> copyMap = perAccountMap_;
perAccountMap_ = new HashMap<PDKey, PData>();
return copyMap;
}
Now, I was able to independently validate the contents of the Map that was being copied above on some multi-core boxes. Intuitively I would have expected the copyMap above to underestimate the entries in the Map - i.e. because it is not synchronized the other synchronized writer threads inserts to the Map will not necessarily be visible to this single thread that takes a copy of it. However the reverse appears to be the case - the copy above appears to consistently have ca. 1% more entries. I can fix the unsynchronized code, but I don't understand the results I observed.
Solution