2011-05-19 123 views

回答

5

编号字符串是不可变的。如果你所做的只是阅读字符串,你绝对没问题。

编辑添加:是的,如果你有一个可变属性,改变属性的值需要同步。

+2

这并不完全准确,因此对'String'的引用也需要是'final'以使它完全线程安全。 – 2011-05-19 14:42:02

+0

@Jarrod Roberson虽然通常是只读的(假设他指的是只读字符串的引用 - 而不是其他任何意义),但这也是不重要的。虽然由于只读基本上是最终的,所以最好将其明确。 – Voo 2011-05-19 16:54:02

+0

你不能引用索引'final' – 2011-05-19 16:57:14

4

不是为String本身,而是为了参考String,当然。

编辑:

作为最终(或以其他方式同步的)并不能保证所有线程可以看出,未声明的变量的引用。尽管许多线程都可以安全读取同一个对象的值,但您需要以某种方式确保所有线程都读取最新的引用。

+0

你能解释一下吗?一个例子可以帮助很多。谢谢。 – rreyes1979 2011-05-19 14:27:10

1

每个字符串的访问是只读(字符串是不可变的),因为String实例的内容不能更改,所以不需要同步。

2

字符串是不可变的对象,因此它们本身就是线程安全的。请注意,像String.toUpperCase()这样的函数不会更改String对象本身,但会返回一个新的String。

StringBuffer和StringBuilder是可变对象。 StringBuffer是线程安全的,StringBuilder不是。

10

String不可变对象是线程安全的,因为它们的内部状态不会改变,并final引用那些String对象是线程安全的。

,如果你有一个非最终引用不可变对象,它没有完全线程安全的。

考虑:

public final String x = "This reference is thread safe, it can never change"; 

x任何引用线程,因为什么x指的是永远无法改变和String对象是不可改变安全

并考虑:

public String s = "This reference is not thread safe, it can change"; 

s任何引用线程安全的,因为s都不可能变成别的东西。那就是:

s = "this is another different immutable String"; 

可以改变s指的是什么。如果您的引用永远不会更改,如果它们预计会发生更改,请将它们声明为volatile,以便JVM知道重新读取引用的内容,而不执行任何可能会错过对s的更改的缓存optomizations。

public volatile String s = "This reference is expected to change, so tell the JVM"; 

对线程安全和更多信息final关键字见The final word on final