РЕДАКТИРОВАТЬ: массив объектов в Java.если вы сделаете ссылку на этот объект энергозависимой, она станет видимой для других потоков, если вы обменяетесь ссылкой на массив.Однако это не относится к самим значениям массива.
Чтобы лучше понять модель памяти Java, существует возможность обойти ее без массива Atomic *.Использование отношения «произошло до» для энергозависимых чтений и обычных записей делает возможным:
, если поток A записывает некоторые энергонезависимые данные, а переменная после , что поток B гарантированно увидитизменения в энергозависимом материале, но только в том случае, если поток B сначала читает переменную.см. также: Связи до появления с энергозависимыми полями и синхронизированными блоками в Java - и их влияние на энергонезависимые переменные?
Для массивов это означает: после записи в массив,запись в некоторую переменную состояния volatile (убедитесь, что запись действительно изменяет переменную состояния volatile!) Когда вы читаете из массива, сначала прочитайте переменную состояния volatile, а затем получите доступ к массиву.В результате энергозависимого чтения все остальные записи также будут видны, если они произошли раньше.
СТАРЫЙ: запись собственной ссылки arr=arr
на самом деле не поможет.
Вы пишете адресмассива arr
, а не значение поля arr[i]
.Таким образом, вы по-прежнему не получаете летучих свойств для arr[i]
(которые вы хотите), а только для адреса хранения arr
.
Ранее упомянутый пост блога Джереми Мэнсона объясняет это подробно: http://jeremymanson.blogspot.com/2009/06/volatile-arrays-in-java.html
Его лучшее решение - использовать массивы Atomic *, а именно AtomicReferenceArray для универсальных типов (также существуют специальные формы дляосновные типы).Я не могу себе представить, что это особенно эффективно, тем более что оно дает вам больше необходимых вам свойств (атомарность >> volatile).
Альтернативой могут быть указательные структуры, в которых контейнеры используют изменяемые поля указателя.Тоже не так эффективно ...