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
Is String get/set threadsafe?
提问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 String
class, or is some locking mechanism required?
由于String
类的不可变特性,这些方法是自动线程安全的,还是需要某种锁定机制?
回答by Matt Ball
No, this is not threadsafe. Foo
is mutable, so if you want to ensure that different threads see the same value of bar
– that is, consistency– either:
不,这不是线程安全的。Foo
是可变的,所以如果你想确保不同的线程看到相同的值bar
——即一致性——要么:
- Make
bar
volatile
, or - Make the methods
synchronized
, or - Use an
AtomicReference<String>
.
- 制作
bar
volatile
, 或 - 制作方法
synchronized
,或 - 使用
AtomicReference<String>
.
The reads and writes of bar
are 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 String
is 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 上,即使在这种情况下最初并不明显。