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
getoperation, 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