java - Why does HashMap.get(key) needs to be synchronized when change operations are synchronized? -
i use .get(...)
, .put(...)
, .clear()
operations multiple threads on 1 hashmap. .put(...)
, .clear()
inside synchronized
block .get(...)
not. can't imagine cause problems in other code i've seen .get()
pretty synchronized.
relevant code 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 just:
synchronized (map) { map.clear(); }
the write operations invalidate caches because of synchronized , get(...)
returns either null or instance. can't see go wrong or improve putting .get(...)
operation synchronized(map)
block.
here 1 simple scenario produce problem on unsynchronized get
:
- thread starts
get
, computes hash bucket number, , gets pre-empted - thread b calls
clear()
, smaller array of buckets gets allocated - thread wakes up, , may run index-out-of-bounds exception
here more complex scenario:
- thread locks map update, , gets pre-empted
- thread b initiates
get
operation, computes hash bucket number, , gets pre-empted - thread wakes up, , continues
put
, , realizes buckets need resizing - thread allocates new buckets, copies old content them, , adds new item
- thread b wakes up, , continues search using old bucket index on new array of buckets.
at point, not going find right item, because in hash bucket @ different index. why get
needs synchronized well.
Comments
Post a Comment