Является ли ConcurrentHashMap::computeIfAbsent атомарным для каждого ключа или для каждой карты ConcurrentHashMap?

#concurrency #locking #concurrenthashmap

Вопрос:

В вызове ConcurrentHashMap::computeIfAbsent я использую немного дорогую функцию сопоставления. Функции сопоставления безопасно выполнять одновременно, если и только если они предназначены для разных ключей. Мне интересно, выполняются ли функции сопоставления одновременно для разных ключей. Если это не так, каждая функция сопоставления будет выполняться по очереди, что приведет к ненужному времени ожидания. Чтобы исправить это, мне нужно было бы написать более сложный код и использовать putIfAbsent. Кто-нибудь знает, выполняются ли функции сопоставления одновременно, если они предназначены для разных ключей?

В документации говорится:

Весь вызов метода выполняется атомарно, поэтому функция применяется не более одного раза для каждого ключа.

Это может дать или не дать ответ на мой вопрос, в зависимости от того, как вы его прочитаете

Комментарии:

1. Блокировка выполняется на хэшбине, поэтому примерно для каждого ключа, но внутренне определяется как «Вероятность конфликта блокировки для двух потоков, обращающихся к различным элементам, составляет примерно 1 / (8 * # элементов) при случайных хэшах».

2. @BenManes спасибо за ответ, похоже, мне не следует использовать computeIfAbsent для этого сценария, так как производительность станет непредсказуемой

3. обычно это не проблема, потому что столкновения редки на больших картах. Вы можете использовать начальную емкость, если карта не будет сильно расти. Поскольку чтение является обычным делом, производительность часто бывает отличной