Безопасна ли маркировка ссылки типа String как Volatile? - PullRequest
4 голосов
/ 06 мая 2020

Я читал несколько сообщений и статей, в которых говорилось, что мы не должны объявлять объекты java как изменчивые, потому что в результате изменчивым становится только ссылка. Вот несколько примеров:

link-1 link-2 link-3

Sonar предлагает следующее: -примитивные поля не должны быть "изменчивыми", однако это также предполагает, что описанная проблема относится к изменяемым объектам. Аналогичным образом, пометка изменяемого поля объекта изменчивым означает, что ссылка на объект является изменчивой, а сам объект - нет.

Мой вопрос: можно ли объявить java String как изменчивую?

Ответы [ 2 ]

4 голосов
/ 06 мая 2020

Поскольку объекты String неизменяемы, только ссылка изменяется такими операторами, как = и +=. Следовательно, volatile безопасен для String, поскольку он применяется к самой ссылке. Это относится и к другим неизменяемым объектам, так же как и к примитивам.

Уточнение:

+= сам по себе не является потокобезопасным даже для изменчивого String, так как он не atomi c и состоит из чтения с последующей записью. Если что-то влияет на объект String между чтением и записью, это может привести к неожиданным результатам. Хотя результирующий String все еще будет действительным, он может иметь неожиданное значение. В частности, некоторые изменения могут «перезаписать» другие изменения. Например, если у вас есть String со значением "Stack ", и один поток пытается добавить "Overflow", а другой пытается добавить "Exchange", есть вероятность, что будет применено только одно изменение. Это относится и к примитивам. Если вам интересно, более подробную информацию об этой конкретной проблеме (в основном в контексте примитивов) можно найти здесь .

0 голосов
/ 06 мая 2020

Java String является последним классом, неизменяемым и потокобезопасным.
Для String нет среднего состояния, не будет путать в многопоточных случаях с lock или synchronize. В этом нет необходимости.

...