String get / set thread是否安全?

时间:2013-02-25 17:17:33

标签: java thread-safety immutability

假设我有以下内容,

public class Foo{
    private String bar;

    public String getBar(){
        return bar;
    }

    public void setBar(String bar){
        this.bar = bar;
    }
}

由于String类的不可变特性,这些方法是自动线程安全的,还是需要一些锁定机制?

4 个答案:

答案 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也会发生同样的(丢失的写入),即使在这种情况下最初并不明显。