Вызывает ли повторное помещение объекта в ConcurrentHashMap отношение памяти "происходит раньше"?

Я работаю с существующим кодом, который имеет хранилище объектов в виде ConcurrentHashMap. Внутри карты хранятся изменяемые объекты, используемые несколькими потоками. По замыслу, ни один из двух потоков не пытается изменить объект одновременно. Меня беспокоит видимость модификаций между потоками.

В настоящее время код объектов имеет синхронизацию на "сеттерах" (охраняемых самим объектом). Нет синхронизации на "геттерах", и члены не являются волатильными. Это, на мой взгляд, означает, что видимость не гарантируется. Однако, когда объект изменяется, он повторно помещается обратно в карту (метод put() вызывается снова, с тем же ключом). Значит ли это, что когда другой поток вытащит объект из карты, он увидит изменения?

Я исследовал это здесь на stackoverflow, в JCIP и в описании пакета java.util.concurrent. В основном я сам себя запутал... но последней каплей, заставившей меня задать этот вопрос, стало описание пакета, в котором говорится:

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

В связи с моим вопросом, включают ли "действия" модификации объектов, хранящихся в карте, перед повторным помещением()? Если все это действительно приводит к видимости в разных потоках, является ли такой подход эффективным? Я относительно новичок в потоках и буду признателен за ваши комментарии.

Edit:

Спасибо всем за ответы! Это был мой первый вопрос на StackOverflow, и он оказался для меня очень полезным.

Я должен согласиться с ответом ptomli, потому что, на мой взгляд, он наиболее четко отражает мою путаницу. То есть, установление отношения "происходит раньше" не обязательно влияет на видимость модификации в этом случае. Мой "вопрос в заголовке" плохо построен относительно моего фактического вопроса, описанного в тексте. Ответ ptomli теперь совпадает с тем, что я прочитал в JCIP: "Чтобы все потоки видели самые последние значения общих изменяемых переменных, потоки чтения и записи должны синхронизироваться на общей блокировке" (стр. 37). Повторное помещение объекта обратно в карту не обеспечивает эту общую блокировку для модификации членов вставленного объекта.

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

8
задан Community 23 May 2017 в 11:55
поделиться