Предисловие: я знаю, что в большинстве случаев использование volatile поля не приведет к измеримому снижению производительности, но этот вопрос более теоретический и нацелен на дизайн с чрезвычайно высокой поддержкой корректности.
У меня есть поле List<Something>
, которое заполняется после построения. Чтобы сохранить некоторую производительность, я хотел бы преобразовать список в карту только для чтения. Для этого в любой момент требуется как минимум переменное поле карты, поэтому сделайте изменения видимыми для всех потоков.
Я думал сделать следующее:
Map map; public void get(Object key){ if(map==null){ Map temp = new Map(); for(Object value : super.getList()){ temp.put(value.getKey(),value); } map = temp; } return map.get(key); }
Это может привести к тому, что несколько потоков будут генерировать карту, даже если они входят в блок get сериализованным способом. Это не было бы большой проблемой, если бы потоки работали на разных идентичных экземплярах карты. Меня больше беспокоит:
Возможно ли, что один поток присваивает новую временную карту полю карты, а затем второй поток видит это map!=null
и, следовательно, обращается к полю карты, не создавая нового, но, к моему удивлению, обнаруживает, что карта пуста, потому что помещенный операции, которые еще не были помещены в какую-либо область общей памяти?
Ответы на комментарии:
- Потоки изменяют временную карту только после того, как она доступна только для чтения.
- Я должен преобразовать список в карту из-за какой-то специальной настройки JAXB, которая не позволяет начать с карты.
get()
нуждается в синхронизации, потому что действительно поток A может видетьmap==null
и вводитьif
, в то время как поток B срабатывает и все еще видитmap==null
и также вводитif
. - person zapl   schedule 26.03.2012