在Java中,是否只读取对字符串的访问需要同步?

时间:2011-05-19 14:20:27

标签: java multithreading thread-safety

是否需要在Java中同步对字符串的只读访问权限?

5 个答案:

答案 0 :(得分: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引用的内容。如果您的引用永远不会更改,请将它们final设置为volatile,您应该声明它们s,以便JVM知道重新读取引用的内容而不执行任何可能错过的缓存验证更改为public volatile String s = "This reference is expected to change, so tell the JVM";

final

有关线程安全和{{1}}关键字的详细信息,请参阅The final word on final

答案 1 :(得分:5)

没有。字符串是不可变的。如果你所做的只是阅读字符串,那你就没事了。

编辑添加:是的,如果您有可变属性,则需要同步更改属性的值。

答案 2 :(得分:4)

本身不是String,而是String的引用。

编辑:

并不保证所有线程都能看到未声明为final(或以其他方式同步)的变量引用。虽然许多线程可以安全地读取相同String对象的值,但您需要以某种方式保证所有线程都在读取最新的参考。

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

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