将 String 类型引用标记为 Volatile 安全吗?

jar*_*ros 8 java string volatile immutability

我读过一些帖子和文章说我们不应该将java对象声明为易失性的,因为这样一来,只有引用变得易失性。这里有些例子:

链接1 链接2 链接3

Sonar 的建议是“非原始字段不应该是“易失性”的”,然而,它也表明所描述的问题涉及可变对象。“类似地,将可变对象字段标记为易失性意味着对象引用是易失性的,但对象本身是易失性的。不是'。

我的问题是:将 java String 声明为 volatile 是否安全?

Eva*_*ley 6

由于String对象是不可变的,因此只有引用会被=和等运算符修改+=。因此, volatile 对于 来说是安全的String,因为它适用于引用本身。这也适用于其他不可变对象,就像它适用于基元一样。

澄清:

+=即使在 volatile 上,它本身也不是线程安全的String,因为它不是原子的,并且由读取和写入组成。如果有什么东西影响了String读写之间的对象,可能会导致意想不到的结果。虽然结果String仍然有效,但它可能具有意想不到的值。特别是,某些更改可能会“覆盖”其他更改。例如,如果您有一个String带有值的a "Stack ",并且一个线程尝试追加,"Overflow"而另一个线程尝试追加,"Exchange"则有可能只应用一项更改。这也适用于基元。如果您有兴趣,可以在此处找到有关此特定问题的更多详细信息(主要是在原语的上下文中)。

  • 是的,您必须向 `+=` 添加同步,最简单的方法是使用 `AtomicReference` 来完成,在这种情况下您不需要 `volatile` (3认同)