Лучше всего использовать java.util.concurrent.ConcurrentHashMap, который спроектирован с нуля для одновременного доступа (чтение и запись).
Использование синхронизации, как вы делаете, работает, но показывает высокий уровень конкуренциии, следовательно, не оптимальная производительность.Коллекция, полученная с помощью Collections.synchronizedMap (), будет делать то же самое (она только оборачивает стандартную коллекцию синхронизированными методами).
ConcurrentHashMap, напротив, использует различные методы для обеспечения безопасности потоков и обеспечения хорошего параллелизма;например, он имеет (по умолчанию) 16 областей, каждая из которых защищена определенной блокировкой, так что до 16 потоков могут использовать ее одновременно.