Подтвердить что ты не робот

Нужен ли мне также volatile для переменных ссылочных типов?

Мы часто используем volatile, чтобы гарантировать, что переменная условия может быть видимой для каждого потока.

Я вижу, что поля volatile все primitive type в коде до сих пор.

В этой области есть поле object? Например:

class a {

   public String str;

   public List list;

}

Если есть некоторые потоки, которые будут обращаться к str и списку, я должен добавить "volatile"?

Я предполагаю, что каждый доступ к object будет получать непосредственно из Heap, а object не будет кэшироваться как примитивный тип.

Правильно ли это?

4b9b3361

Ответ 1

Вы должны различать ссылку на объект и фактический объект.

  • Для ссылки необходим ваш модификатор поля. Когда вы меняете ссылку на другой объект (т.е. Ссылаетесь на другую строку), это изменение может не заметить другой поток. Если вы хотите обеспечить видимость, вы должны использовать final или volatile.

  • Модификатор поля не влияет на фактический объект на кучу. Вместо этого, как вы видите, каждое поле этого объекта определяется его собственным модификатором поля в соответствии с теми же правилами (это volatile или final? Если нет, видимость для параллельных потоков не выполняется)

Итак, ответ: Да, вы должны добавить volatile или final. Однако стилистически было бы лучше сделать поле окончательным. Он имеет тот же эффект Thread-wise, но также является более сильным утверждением: это поле не может быть изменено - вот почему он может быть незаметно кэширован JVM. И по той же причине он имеет небольшое преимущество в производительности по сравнению с volatile, Java не заботится о том, изменилось ли поле снова и не нужно добавлять служебные данные.

Ответ 2

Вы добавляете volatile keyword, чтобы сообщить компилятору, что он связан с change. так что все потоки

повторите подтверждение того, что их local cached copy совпадает с тем, что у исходного, если есть изменения

обновляет его. и вы обычно находите его с примитивами, потому что обычно примитивные значения увеличиваются

или уменьшено и т.д. различными потоками. но Object, особенно List, никогда не изменится с момента его просто

ссылка на объект. если вы назначаете разные объекты одной и той же переменной во время выполнения

то вы можете

делать..