问题
I've read some posts and articles saying that we shouldn't declare java objects as volatile, because as a result, only the reference becomes volatile. Here are some examples:
link-1 link-2 link-3
What Sonar suggests is 'Non-primitive fields should not be "volatile"', however, it also suggests that the problem described refers to mutable objects 'Similarly, marking a mutable object field volatile means the object reference is volatile but the object itself is not'.
My question is: is it safe to declare java String as volatile?
回答1:
Because String
objects are immutable, only the reference is modified by operators like =
and +=
. Therefore, volatile is safe for String
, as it applies to the reference itself. This applies to other immutable objects as well, just as it does to primitives.
Clarification:
+=
itself is not thread-safe even on a volatile String
, as it is not atomic and consists of a read followed by a write. If something affects the String
object between the read and write, it may lead to unexpected results. While the resulting String
will still be valid, it may have an unexpected value. In particular, some changes may "overwrite" other changes. For instance, if you have a String
with the value "Stack "
and one thread tries to append "Overflow"
while the other tries to append "Exchange"
, there is a possibility that only one change will be applied. This applies to primitives as well. If you are interested, more details about this particular issue (mostly in the context of primitives) can be found here.
回答2:
Java String is final Class, immutable and thread-safe.
There is no middle state for String, will not confuse in the multi-thread cases with lock
or synchronize
.
There is no need to do that.
来源:https://stackoverflow.com/questions/61628641/is-marking-string-type-reference-as-volatile-safe