The ConcurrentHashMap is thread safe without locking the entire table but it doesn't remove the race conditions like if we query for a key and at that time the key is not there, so in the next instruction we add the key's entry to the map. Between the two things, any other thread may have added the key and the user will inadvertently replace that with his own entry.
That could be avoided by putting the 2 statements in a synchronize block, though this particular race condition can be avoided using putIfAbsent. But my point is that we have to use our own synchronizations in the case of ConcurrentHashMap too, when putIfAbsent is not suffiecient. Is that right ?