java 字符串获取/设置线程安全吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15072578/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 18:23:48  来源:igfitidea点击:

Is String get/set threadsafe?

javathread-safetyimmutability

提问by mre

Let's say I have the following,

假设我有以下内容,

public class Foo{
    private String bar;

    public String getBar(){
        return bar;
    }

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

Are these methods automatically threadsafe due to the immutable nature of the Stringclass, or is some locking mechanism required?

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

回答by Matt Ball

No, this is not threadsafe. Foois mutable, so if you want to ensure that different threads see the same value of bar– that is, consistency– either:

不,这不是线程安全的。Foo是可变的,所以如果你想确保不同的线程看到相同的值bar——即一致性——要么:

  • Make barvolatile, or
  • Make the methods synchronized, or
  • Use an AtomicReference<String>.
  • 制作barvolatile, 或
  • 制作方法synchronized,或
  • 使用AtomicReference<String>.

The reads and writes of barare themselves atomic, but atomicity is not thread safety.

的读取和写入bar本身是原子的,但原子性不是线程安全的。

http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html

http://docs.oracle.com/javase/tutorial/essential/concurrency/atomic.html



For in-depth coverage of Java concurrency, grab a copy of Java Concurrency in Practice (aka JCIP).

要深入了解 Java 并发,请获取Java Concurrency in Practice (aka JCIP)的副本。

回答by Brian Agnew

You're setting references, and as such String's immutability doesn't come into play. You're not affecting the contents of String.

您正在设置引用,因此String的不变性不会发挥作用。您不会影响String.

回答by duffymo

No, not safe.

不,不安全。

This is Foo mutable behavior; String's immutability does not accrue to Foo.

这是 Foo 可变行为;String 的不变性不会归于 Foo。

public class Foo{
    private String bar;

    public synchronized String getBar(){
        return bar;
    }

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

回答by Theodoros Chatzigiannakis

No, it's not thread safe.

不,它不是线程安全的。

While Stringis immutable, the issue comes from the field of Foo. To make this more apparent, consider for example a method whose job would be to append(rather than replace) the value of bar. When it's called from multiple threads, some writes could be lost. The same (lost writes) can happen with your simple setter too, even if it's not obvious initially in this case.

虽然String是不可变的,但问题来自Foo. 为了使这一点更加明显,例如考虑一种方法,其工作是附加(而不是替换) 的值bar。当它从多个线程调用时,一些写入可能会丢失。同样的(丢失的写入)也可能发生在您的简单 setter 上,即使在这种情况下最初并不明显。