Нужно ли использовать поточно-ориентированную реализацию Map при чтении только из нее? - PullRequest
7 голосов
/ 10 мая 2011

Если я сделаю следующее.

  • Создать HashMap (в конечном поле)
  • Заполнить HashMap
  • Wash HashMap с неизменяемой оболочкой Карта
  • Запускать другие темы, которые будут иметь доступ к карте, но не изменять ее.

Насколько я понимаю, карта была "благополучно опубликована", потому что другие потоки были запущены после того, как карта была полностью заполнена, поэтому я думаю, что можно получить доступ к карте из нескольких потоков, поскольку ее нельзя изменить после этой точки. 1013 *

Это правильно?

Ответы [ 5 ]

11 голосов
/ 10 мая 2011

Это прекрасно для самой карты. Но вам нужно понять, что если сделать карту не изменяемой, то только сама карта станет неизменной, а не ее ключей и значений. Так, если у вас есть, например, Map<String, SomeMutableObject>, например, Map<String, List<String>>, потоки все равно смогут изменять значение, например, map.get("foo").add("bar");. Чтобы избежать этого, вы также хотели бы сделать ключи / значения неизменяемыми / неизменяемыми.

1 голос
/ 10 мая 2011

Насколько я понимаю, карта была "благополучно опубликована", потому что другие потоки были запущены после того, как карта была полностью заполнена, поэтому я думаю, что можно получить доступ к карте из нескольких потоков, поскольку это невозможноизменено после этой точки.

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

Это обсуждается в этом блоге :

[...] Так работает Collections.unmodifiableMap ().

[...]

Из-за особого значения ключевого слова "final" экземпляры этого класса могут совместно использоваться несколькими потоками без какой-либо дополнительной синхронизации ;когда другой поток вызывает get () для экземпляра, он гарантированно получает объект, который вы помещаете на карту, без какой-либо дополнительной синхронизации.Вероятно, вам следует использовать что-то поточно-ориентированное для выполнения передачи обслуживания между потоками (например, LinkedBlockingQueue или что-то в этом роде), но если вы забудете это сделать, то у вас все еще есть гарантия.

0 голосов
/ 11 мая 2011

Короче говоря, нет необходимости в том, чтобы карта была поточно-ориентированной, если считывания не являются разрушающими, а ссылка на карту безопасно публикуется для клиента.

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

Все, что изменяет карту после этих вызововВ отношении чтения клиента с карты небезопасно публикуется.

У нас есть, например, CopyOnWriteMap , который имеет не поточно-ориентированную карту, которая копируется при каждой записи.Это происходит настолько быстро, насколько это возможно в ситуациях, когда операций чтения намного больше, чем операций записи (хорошим примером является кэширование данных конфигурации).

Тем не менее, если на самом деле цель состоит в том, чтобы не менять карту, установка неизменяемой версии карты в поле - это всегда лучший путь, поскольку он гарантирует, что клиент увидит правильную вещь.

Наконец, есть некоторые реализации Map с деструктивным чтением, такие как LinkedHashMap с упорядочением доступа или WeakHashMap, где записи могут исчезать.Эти типы карт должны быть доступны последовательно.

0 голосов
/ 10 мая 2011

Неизменяемая карта рождается поточно-ориентированной.Вы можете использовать ImmutableMap of Guava.

0 голосов
/ 10 мая 2011

Вы правы.Нет необходимости обеспечивать эксклюзивный доступ к структуре данных различными потоками с помощью mutex'ов или иным образом, поскольку он неизменен .Как правило, это значительно повышает производительность.

Также обратите внимание, что если вы оборачиваете только оригинальную Карту, а не создаете копию, то есть вызов метода немодифицируемых делегатов Map далее во внутреннюю HashMap, изменение базовой карты может привести к проблемам состояния гонки..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...