假设我有以下内容,
public class Foo{
private String bar;
public String getBar(){
return bar;
}
public void setBar(String bar){
this.bar = bar;
}
}
由于String
类的不可变特性,这些方法是自动线程安全的,还是需要一些锁定机制?
答案 0 :(得分:19)
不,这不是线程安全的。 Foo
是可变的,因此如果您想确保不同的主题看到bar
的相同值 - 即一致性 - :
bar
volatile
或synchronized
或AtomicReference<String>
。 bar
的读写本身就是原子的,但原子性不是线程安全的。
http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html
要深入了解Java并发,请抓取Java Concurrency in Practice (aka JCIP)。
的副本答案 1 :(得分:7)
您正在设置引用,因此String
的不变性不起作用。您没有影响String
的内容。
答案 2 :(得分:5)
不,不安全。
这是Foo可变行为;字符串的不变性不会归于Foo。
public class Foo{
private String bar;
public synchronized String getBar(){
return bar;
}
public synchronized void setBar(String bar){
this.bar = bar;
}
}
答案 3 :(得分:3)
不,这不是线程安全的。
虽然String
是不可变的,但问题来自Foo
字段。为了使这一点更加明显,请考虑一个方法,其工作是追加(而不是替换)bar
的值。当从多个线程调用它时,某些写入可能会丢失。使用简单的setter也会发生同样的(丢失的写入),即使在这种情况下最初并不明显。