2017-02-22 41 views
1

У меня есть этот код, который имеет общую хэш-карту, инициализированную в статическом блоке. Я не раскрываю hashmap, и он используется только для чтения (get и containsKey). Я хотел убедиться, что это потокобезопасно.Java hashmap readonly thread security

public class MyClass { 
    private static final Map<String, MyObject> myMap; 

    static { 
     myMap = new MyLoader().load() 
    } 

    public MyClass() { 
     if (containsKey(someKey)) { 
      // do something 
     } 
     myMap.get(something) 
    } 

    static boolean containsKey(String key) { 
     // do some other stuff 
     return myMap.containsKey(key) 
    } 
} 
+0

Пока нить не модифицирует карту (добавление или удаление пары ключ/значение или изменение существующего значения), в то время как другие потоки читают, тогда она является потокобезопасной. Я не включил мутирующий ключевой объект, потому что это вызывает проблемы, независимо от потоковой передачи. –

+0

Он не подвергается воздействию и не изменен в классе –

+0

Является ли метод вызовом 'new MyLoader(). Load()' _only_ вещь во всем приложении, которое записывает на карту, и делает это только когда-либо записывая его в этом один звонок? –

ответ

2

Предполагая, что new MyLoader().load() возвращает карту, которая полностью инициализирован со всеми данными и которые не изменяются после этого, то это безопасно для всех потоков для извлечения данных из этой карты одновременно. Javadoc для HashMap говорит: «Если несколько потоков обращаются к карте хешей одновременно, и по крайней мере один из потоков изменяет структуру по структуре, она должна быть синхронизирована извне». Поэтому, если нить не модифицирует карту, то ее не нужно синхронизировать.

В качестве меры безопасности, ваш метод load() должен обеспечивать неизменность:

public Map<String, MyObject> load() { 
    Map<String, MyObject> mymap = new HashMap<>(); 
    mymap.put(...); 
    ... 
    return Collections.unmodifiableMap(mymap); 
} 

Таким образом, вам не нужно беспокоиться, что какой-то поток в какой-то код, который вы не знакомы с может непреднамеренно изменить карту. Он не сможет.