ConcurrentHashMap contains values, but size() method returns 0
<p>Experiencing weird behavior of <code>ConcurrentHashMap</code>: at first the map gets modified concurrently by several threads using compare-and-set operations like <code>putIfAbsent()</code> and <code>remove()</code>. After some time (tens of seconds or even a minute) another thread checks if the map is empty or not using two methods:</p>

<ol>
<li>calling <code>myMap.isEmpty()</code> method</li>
<li>trying to see if there are any entries in iterator: <code>myMap.entrySet().iterator().hasNext()</code></li>
</ol>

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

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

<p>Wonder if this is expected behavior of <code>ConcurrentHashMap</code>. </p>

<p>Documentation states that:</p>

<blockquote>
  <p>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.</p>
</blockquote>

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