Нужно ли использовать volatile для переменных ссылочных типов? - PullRequest
24 голосов
/ 16 августа 2011

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

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

Имеет ли поле object эту проблему?Например:

class a {

   public String str;

   public List list;

}

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

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

Это верно?

Ответы [ 2 ]

28 голосов
/ 16 августа 2011

Необходимо различать ссылку на объект и реальный объект.

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

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

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

2 голосов
/ 16 августа 2011

Вы добавляете volatile keyword, чтобы сообщить компилятору, что он привязан к change. так что все потоки повторно подтверждают, что их local cached copy такой же, как у исходного, если есть изменения, он обновляет его. и вы найдете это обычно с Примитивами, потому что обычно примитивные значения увеличиваются или уменьшаются и т. д. различными потоками. но объект, особенно список никогда не изменится, так как его просто ссылка на объект. если вы присваиваете разные объекты одной и той же переменной, во время выполнения вы можете сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...