Нужен ли мне также volatile для переменных ссылочных типов?
Мы часто используем volatile
, чтобы гарантировать, что переменная условия может быть видимой для каждого потока.
Я вижу, что поля volatile
все primitive type
в коде до сих пор.
В этой области есть поле object
? Например:
class a {
public String str;
public List list;
}
Если есть некоторые потоки, которые будут обращаться к str и списку, я должен добавить "volatile"?
Я предполагаю, что каждый доступ к object
будет получать непосредственно из Heap
, а object
не будет кэшироваться как примитивный тип.
Правильно ли это?
Ответы
Ответ 1
Вы должны различать ссылку на объект и фактический объект.
-
Для ссылки необходим ваш модификатор поля. Когда вы меняете ссылку на другой объект (т.е. Ссылаетесь на другую строку), это изменение может не заметить другой поток. Если вы хотите обеспечить видимость, вы должны использовать final
или volatile
.
-
Модификатор поля не влияет на фактический объект на кучу. Вместо этого, как вы видите, каждое поле этого объекта определяется его собственным модификатором поля в соответствии с теми же правилами (это volatile
или final
? Если нет, видимость для параллельных потоков не выполняется)
Итак, ответ: Да, вы должны добавить volatile
или final
. Однако стилистически было бы лучше сделать поле окончательным. Он имеет тот же эффект Thread-wise, но также является более сильным утверждением: это поле не может быть изменено - вот почему он может быть незаметно кэширован JVM. И по той же причине он имеет небольшое преимущество в производительности по сравнению с volatile
, Java не заботится о том, изменилось ли поле снова и не нужно добавлять служебные данные.
Ответ 2
Вы добавляете volatile keyword
, чтобы сообщить компилятору, что он связан с change
. так что все потоки
повторите подтверждение того, что их local cached copy
совпадает с тем, что у исходного, если есть изменения
обновляет его. и вы обычно находите его с примитивами, потому что обычно примитивные значения увеличиваются
или уменьшено и т.д. различными потоками. но Object, особенно List, никогда не изменится с момента его просто
ссылка на объект. если вы назначаете разные объекты одной и той же переменной во время выполнения
то вы можете
делать..