Обратите внимание, что изменение ссылки, предложенное другими, может вызвать проблемы, если вы полагаетесь на то, что карта некоторое время не меняется (например, if (map.contains(key)) {V value = map.get(key); ...}
. Если вам это нужно, вам следует сохранить локальную ссылку на карту:
static Map<U,V> map = ...;
void do() {
Map<U,V> local = map;
if (local.contains(key)) {
V value = local.get(key);
...
}
}
РЕДАКТИРОВАТЬ:
Предполагается, что вы не хотите дорогостоящей синхронизации для ваших клиентских потоков. В качестве компромисса вы позволяете клиентским потокам завершить свою работу, которую они уже начали до того, как ваша карта изменилась - игнорируя любые изменения карты, произошедшие во время ее работы. Таким образом, вы можете безопасно сделать некоторые предположения о вашей карте - например, что ключ присутствует и всегда отображается на одно и то же значение в течение одного запроса. В приведенном выше примере, если ваш поток чтения изменил карту сразу после того, как клиент назвал map.contains(key)
, клиент мог бы получить значение NULL для map.get(key)
- и вы почти наверняка завершили бы этот запрос с NullPointerException. Поэтому, если вы выполняете многократное чтение карты и вам нужно сделать некоторые предположения, как упомянуто выше, проще всего сохранить локальную ссылку на (возможно, устаревшую) карту.
Здесь ключевое слово volatile не обязательно. Было бы просто убедиться, что новая карта используется другими потоками, как только вы измените ссылку (map = newMap
). Без энергозависимости последующее чтение (local = map
) могло бы все еще вернуть старую ссылку в течение некоторого времени (хотя мы говорим о менее чем наносекунде) - особенно в многоядерных системах, если я правильно помню. Мне было бы все равно, но если вы чувствуете необходимость в этой дополнительной красоте многопоточности, вы можете свободно использовать ее;)