Я работаю с существующим кодом, который имеет хранилище объектов в форме ConcurrentHashMap. Внутри карты хранятся изменяемые объекты, которые используются несколькими потоками. Никакие два потока не пытаются изменить объект сразу по проекту. Мое беспокойство касается видимости изменений между потоками.
В настоящее время код объектов синхронизируется с «сеттерами» (охраняется самим объектом). На «получателях» нет синхронизации, и члены не изменчивы. Для меня это будет означать, что видимость не гарантируется. Однако, когда объект модифицируется, он повторно помещает обратно в карту (метод put()
вызывается снова, тот же ключ). Означает ли это, что когда другой поток вытаскивает объект из карты, он видит изменения?
Я исследовал это здесь на stackoverflow, в JCIP и в описании пакета для java.util.concurrent. Я в основном запутался, я думаю ... но последняя капля, которая заставила меня задать этот вопрос, была из описания пакета, оно гласит:
Действия в потоке перед помещением объекта в любую параллельную коллекцию, выполняемые перед действиями после доступа или удаления этого элемента из коллекции в другом потоке.
Что касается моего вопроса, включают ли "действия" модификации объектов, сохраненных на карте перед повторной установкой ()? Если все это приводит к видимости между потоками, является ли это эффективным подходом? Я относительно новичок в темах и буду признателен за ваши комментарии.
Edit:
Спасибо всем за ответы! Это был мой первый вопрос о StackOverflow, и он мне очень помог.
Я должен идти с ответом ptomli , потому что я думаю, что это наиболее ясно решило мою путаницу. То есть установление отношения «происходит до» не обязательно влияет на видимость модификации в этом случае. Мой «заглавный вопрос» плохо составлен относительно моего фактического вопроса, описанного в тексте. Ответ ptomli теперь совпадает с тем, что я прочитал в JCIP : «Чтобы все потоки видели самые последние значения общих изменяемых переменных, потоки чтения и записи должны синхронизировать по общей блокировке »(стр. 37). Повторное помещение объекта обратно на карту не обеспечивает эту общую блокировку для изменения элементов вставленного объекта.
Я ценю все советы по изменению (неизменяемые объекты и т. Д.), И я полностью согласен с этим. Но для этого случая, как я уже упоминал, нет параллельной модификации из-за тщательной обработки потоков. Один поток изменяет объект, а другой поток позже читает объект (при этом CHM является конвейером объекта). Я думаю, что CHM недостаточно, чтобы гарантировать, что последующий выполняющий поток увидит изменения от первого, учитывая ситуацию, которую я предоставил. Тем не менее, я думаю, что многие из вас правильно ответили на заглавный вопрос .