2009-11-05 3 views
1

Обычно (т.е.. Не одновременно), putAll() не может быть более эффективным, чем использование Лота звонков put(), даже если предположить, что вы исключите затраты на строительство другой карты, которые вы передаете в putAll(). Это связано с тем, что putAll() необходимо будет перебирать пройденные элементы карты, а также запускать алгоритм для добавления каждой пары значений ключа к карте, выполняемой put().ConcurrentHashMap и putAll() метод

Но для ConcurrentHashMap имеет смысл создать обычную карту, а затем использовать putAll() для ее обновления? Или я должен просто сделать 10 (или 100 или 1000) звонков на put()?

Выполняется ли ответ для нескольких вызовов на putIfAbsent()?

Спасибо!

+0

Вы даже используете потоки для заполнения ConcurrentHashMap? Если нет, то не будет никакой разницы между putAll() или 100 последовательными put() – jitter

+0

Да, (по крайней мере) один поток записывает в ConcurrentHashMap, и из него читают несколько потоков. – Rudiger

+0

PutAll() похож на автоматизированный процесс добавления нескольких элементов в CHM, чем делать это самостоятельно один за другим. – AKS

ответ

3

Первый (в основном) потокобезопасный Карта в сборниках Java была синхронизирована HashMap с использованием Collections.synchronizedMap(). Он работал только за одну операцию за раз. Java 5 добавила ConcurrentHashMap, который работает по-разному. В основном Map разделен на ломтики. Операция put() будет блокировать только соответствующий срез. Он также добавил потокобезопасные примитивы, такие как putIfAbsent().

Причина, по которой я объясняю это, заключается в том, что putAll() может быть более или менее эффективным в зависимости от того, как он реализован. Он может работать, блокируя всю карту, что может быть фактически более эффективным, чем попытка получить отдельные блокировки на каждом put(). Или это может сработать, сделав кучу put() вызовов в любом случае, и в этом случае нет большой разницы.

Так что, если это имеет смысл для вашего кода, и вы делаете много обновлений сразу, я бы использовал putAll(), если это не putIfAbsent(), что вы после.

Edit: Я только что проверил, то Java 6 ConcurrentHashMap реализует putAll() как петли put() операций, так что не лучше или хуже, чем делать это самостоятельно.

+0

Я подумал, что может получить один замок для всех обновлений, но, думаю, нет. Я просто сделаю индивидуальные вызовы 'Conc()' ConcurrentHashMap' и избегаю затрат на строительство другой Карты. – Rudiger

+0

Приятно проверять источник, однако я конкретизирую «не лучше или хуже», так как более четкий код более понятный код ^^ – 2009-11-05 02:49:49

+0

Приятно иметь более четкий код, но использовать 'putAll()' мне нужно было бы создать новая карта (которая вызывает множественные вызовы 'put()' в любом случае). – Rudiger

2

putAll() только делегирует put(). Нет необходимости создавать промежуточную карту, если у вас ее уже нет. Вы можете видеть это в исходном коде, и неважно, какую реализацию Java вы используете, поскольку код является общедоступным и совместно используется всеми.

Отметьте, что putAll() не является атомарным, а просто имеет гарантию, что каждый отдельный put() является атомарным.

Смежные вопросы