Reputation: 44240
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?
Upvotes: 9
Views: 15434
Reputation: 359786
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:
bar
volatile
, orsynchronized
, orAtomicReference<String>
.The reads and writes of bar
are themselves atomic, but atomicity is not thread safety.
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).
Upvotes: 20
Reputation: 308763
No, not safe.
This is Foo mutable behavior; String's immutability does not accrue to Foo.
public class Foo{
private String bar;
public synchronized String getBar(){
return bar;
}
public synchronized void setBar(String bar){
this.bar = bar;
}
}
Upvotes: 5
Reputation: 29213
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.
Upvotes: 3
Reputation: 272257
You're setting references, and as such String
's immutability doesn't come into play. You're not affecting the contents of String
.
Upvotes: 7