Как при использовании блокировки, так и при копировании при записи достигается (практически) одинаковая функциональность. Ни один из них по своей природе не лучше другого.
Как правило, копирование при записи выполняется лучше, когда много операций чтения, но очень мало операций записи. Это связано с тем, что в среднем чтение дешевле, чем при использовании блокировки, а запись дороже из-за копирования. Когда у вас много записей, лучше использовать блокировку.
Почему записи дороже, вероятно, очевидно (вам нужно копировать всю карту при каждой записи, да). Причина чтения дешевле:
volatile Map<K, V> internalMap = new HashMap<>();
Чтение InternalMap не требует получения блокировки (подробнее см. Разница между volatile и синхронизированными в Java ). Как только потоки получили ссылку на internalMap
, они могут просто продолжать работать с этой копией (например, перебирая записи), не координируя с другими потоками, потому что гарантируется, что она не будет видоизменена. Столько потоков, сколько необходимо, могут обработать одну копию (снимок) карты.
Чтобы объяснить по аналогии, представьте, что автор готовит статью, и у них есть несколько человек, работающих в качестве проверщиков фактов. С замком только один из них может работать на сквозняке. С копией при записи автор отправляет неизменный снимок (копию) куда-то, что контролеры фактов могут захватить и выполнить свою работу - пока они выполняют свою работу, они могут читать снимок по мере необходимости (вместо того, чтобы прерывать автора каждый раз, когда они забыл части статьи и т. д.).
Блокировка Java с годами улучшилась и, следовательно, разница невелика, но в экстремальных условиях отсутствие необходимости в блокировке / отсутствие координации между потоками может привести к более высокой пропускной способности и т. Д.