синхронизированный против блокировки против синхронизированной карты

#java #synchronization

#java #синхронизация

Вопрос:

Мне нужно синхронизировать мои обращения к hashmap. Вот мои варианты

  1. Я знаю, что могу использовать ключевое слово Synchronize. это один из вариантов. Могу ли я использовать саму карту?
  2. в настоящее время у меня есть метод get, который, если объект не существует, создает его и помещает на карту. Я могу синхронизировать метод.
  3. Я могу использовать блок синхронизации
  4. Я могу использовать
    Map m = Коллекции.synchronizedMap(новая хэш-карта (…)); в моем коде.

Я склонен делать 4, потому что это звучит проще всего. Есть предложения?

Ответ №1:

Я бы посоветовал вам не синхронизировать методы и не блокировать саму карту. Обычно я предпочитаю использовать отдельный объект блокировки, который используется только для блокировки и о котором известно только в классе, которому принадлежит карта.

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

Другой вариант — использовать ConcurrentHashMap . Смотрите документы для семантики. Вероятно, это самый простой подход, если он ведет себя так, как вам нужно.

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

1. Спасибо. почему бы не использовать саму карту?

2. @useer450602: Мне нравится точно знать, какой код может в конечном итоге попытаться получить блокировку — если я не контролирую блокировку, это затрудняет рассуждения об этом. Единственный способ убедиться, что никакой другой код не может что-либо заблокировать, — это сделать это объектом, о начале которого знает только ваш код.

Ответ №2:

Вы могли бы использовать ConcurrentHashMap.putIfAbsent(), который может делать то, что вы хотите, без синхронизации.