Идея состоит в том, что ConcurrentHashMap
использует сегменты, как и любая другая основанная на хэше структура. Когда вы просматриваете (remove
) запись, она использует hashCode, чтобы найти bucket , где запись может находиться в первую очередь, а затем немедленно ее удалить.
Вопрос в том, сможете ли вы обнаружить / увидеть это удаление, которое действительно произошло; например, вы выполняете итерацию и распечатываете содержимое CHM
и одновременно удаляете некоторые записи. Если вы уже "посетили" какой-либо сегмент через, например, forEach
(и обход происходит на основе сегмента), и запись была удалена из этого сегмента - вы ее не заметите.
С другой стороны, если вы удалите и войдете из «еще не посещенного» ведра - вы заметите удаление.
Это, например, причина, по которой size
возвращает известный на данный момент размер - он считает, например, записи из bucketA, а затем кто-то удалит некоторые из этих записей, CHM
не вернется или не выполнит синхронизацию с посчитай это снова.
Также есть несколько очень хороших комментариев для чтения здесь