I'm working on something where I have a Collections.synchronizedMap defined.
In one thread A, it will just get the value, and put an updated value so it is not a problem.
In another thread B, it will iterate through the entries and then based on the values of an entry, do some comparisons, and if it matches some condition, it will delete that entry from the map.
My understanding is that a synchronized Map will block access.
But is it possible that thread B gets an entry, then thread A updates the value, and then thread B deletes the value because it matches some condition, but it shouldn't have because of the value thread A updated it to. And what would be the best implementation to work around this?
It sounds like you just need to synchronize the "fetch, check and delete" part. For example:
Iterable<String> keys;
synchronized (map) {
keys = new ArrayList<>(map.keySet());
}
for (String key : keys) {
synchronized (map) {
Integer value = map.get(key);
// The other thread won't be able to update the value at this point
if (value != null && value < 0) {
map.remove(key);
}
}
}
Your updating thread may need to do the same thing - it's unclear from your description whether it needs to "see" the deletion.
See more on this question at Stackoverflow