将 String 类型引用标记为 Volatile 安全吗?
Is marking String type reference as Volatile safe?
我读过一些帖子和文章说我们不应该将 java 对象声明为 volatile,因为这样一来,只有引用变成了 volatile。以下是一些示例:
Sonar 提示的是 'Non-primitive fields should not be "volatile"',但是,它也提示所描述的问题涉及可变对象 'Similarly, marking a mutable object field volatile means the object reference is volatile but the object itself is not'。
我的问题是:将 java String 声明为 volatile 是否安全?
Java 字符串是最终的 Class,不可变且线程安全。
String没有中间状态,在多线程的情况下不会和lock
或synchronize
混淆。
没有必要这样做。
因为String
对象是不可变的,只有引用被=
和+=
等操作符修改。因此,volatile 对于 String
是安全的,因为它适用于引用本身。这也适用于其他不可变对象,就像它对基元一样。
澄清:
+=
本身不是线程安全的,即使在 volatile String
上也是如此,因为它不是原子的并且由读取和写入组成。如果在读写之间有什么影响了String
对象,可能会导致意想不到的结果。虽然生成的 String
仍然有效,但它可能具有意外值。特别是,某些更改可能 "overwrite" 其他更改。例如,如果您有一个值为 "Stack "
的 String
,并且一个线程尝试追加 "Overflow"
而另一个线程尝试追加 "Exchange"
,则有可能只有一个更改将被应用。这也适用于原语。如果您有兴趣,可以在 .
中找到有关此特定问题的更多详细信息(主要是在原语的上下文中)
我读过一些帖子和文章说我们不应该将 java 对象声明为 volatile,因为这样一来,只有引用变成了 volatile。以下是一些示例:
Sonar 提示的是 'Non-primitive fields should not be "volatile"',但是,它也提示所描述的问题涉及可变对象 'Similarly, marking a mutable object field volatile means the object reference is volatile but the object itself is not'。
我的问题是:将 java String 声明为 volatile 是否安全?
Java 字符串是最终的 Class,不可变且线程安全。
String没有中间状态,在多线程的情况下不会和lock
或synchronize
混淆。
没有必要这样做。
因为String
对象是不可变的,只有引用被=
和+=
等操作符修改。因此,volatile 对于 String
是安全的,因为它适用于引用本身。这也适用于其他不可变对象,就像它对基元一样。
澄清:
+=
本身不是线程安全的,即使在 volatile String
上也是如此,因为它不是原子的并且由读取和写入组成。如果在读写之间有什么影响了String
对象,可能会导致意想不到的结果。虽然生成的 String
仍然有效,但它可能具有意外值。特别是,某些更改可能 "overwrite" 其他更改。例如,如果您有一个值为 "Stack "
的 String
,并且一个线程尝试追加 "Overflow"
而另一个线程尝试追加 "Exchange"
,则有可能只有一个更改将被应用。这也适用于原语。如果您有兴趣,可以在