Christian
Christian

Reputation: 3721

Why does HashMap.get(key) needs to be synchronized when change operations are synchronized?

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

Answers (1)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726809

Here is one simple scenario that would produce a problem on unsynchronized get:

  • Thread A starts get, computes the hash bucket number, and gets pre-empted
  • Thread B calls clear(), so a smaller array of buckets gets allocated
  • Thread A wakes up, and may run into the index-out-of-bounds exception

Here is a more complex scenario:

  • Thread A locks the map for an update, and gets pre-empted
  • Thread B initiates a get operation, computes the hash bucket number, and gets pre-empted
  • Thread A wakes up, and continues the put, and realizes that the buckets need resizing
  • Thread A allocates new buckets, copies old content into them, and adds the new item
  • Thread B wakes up, and continues the search using the old bucket index on the new array of buckets.

At 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

Related Questions