Reputation: 3721
I use the .get(...)
, .put(...)
and .clear()
operations from multiple threads on one HashMap. .put(...)
and .clear()
are inside a synchronized
block but .get(...)
is not. I can't imagine that this will cause problems but in other code I've seen .get()
is pretty much always synchronized.
relevant code for get/put
Object value = map.get(key);
if(value == null) {
synchronized (map) {
value = map.get(key); // check again, might have been changed in between
if(value == null) {
map.put(key, new Value(...));
}
}
}
and clear is just:
synchronized (map) {
map.clear();
}
The write operations will invalidate caches because of the synchronized and the get(...)
returns either null or an instance. I can't really see what could go wrong or what would improve by putting the .get(...)
operation into a synchronized(map)
block.
Upvotes: 6
Views: 1549
Reputation: 726809
Here is one simple scenario that would produce a problem on unsynchronized get
:
get
, computes the hash bucket number, and gets pre-emptedclear()
, so a smaller array of buckets gets allocatedHere is a more complex scenario:
get
operation, computes the hash bucket number, and gets pre-emptedput
, and realizes that the buckets need resizingAt this point, thread B is probably not going to find the right item, because it is very likely to be in a hash bucket at a different index. That is why get
needs to be synchronized as well.
Upvotes: 6