ConcurrentHashMap contains values, but size() method returns 0

Viewed 1361

Experiencing weird behavior of ConcurrentHashMap: at first the map gets modified concurrently by several threads using compare-and-set operations like putIfAbsent() and remove(). After some time (tens of seconds or even a minute) another thread checks if the map is empty or not using two methods:

  1. calling myMap.isEmpty() method
  2. trying to see if there are any entries in iterator: myMap.entrySet().iterator().hasNext()

Surprisingly these two methods give different results. isEmpty() returns true and iterator.hasNext() returns true right after that. The calls are performed without any pause in between and no write operations are performed on the map at this time.

Please note, that according to logs there are no situations when isEmpty() returns false and iterator.hasNext() returns false at the same time. So it is always isEmpty() method not 'seeing' any entries in the map.

Wonder if this is expected behavior of ConcurrentHashMap.

Documentation states that:

Bear in mind that the results of aggregate status methods including size, isEmpty, and containsValue are typically useful only when a map is not undergoing concurrent updates in other threads. Otherwise the results of these methods reflect transient states that may be adequate for monitoring or estimation purposes, but not for program control.

That gives the idea that methods like size() and isEmpty() are expected to return values consistent with actual contents of the map when there are no ongoing write operations.

1 Answers
Related