Let's say I have the following class that will be read heavily, but only written to occasionally. It will be used in a multi-threaded web app, so it needs to be thread safe:
public class Foo {
private volatile String foo;
public String getFoo() {
return foo;
}
public synchronized String setFoo(String in) {
this.foo = in;
}
}
Java Concurrency (http://www.ibm.com/developerworks/java/library/j-jtp06197/index.html) states that this is a fragile way to protect write access while improving read access. What is a stronger alternative to this pattern? Or any alternative if foo will need to mutable in a read-heavy environment? Thank you.
Volatile provides fast thread-safe lock-free access to a field without synchronization
private volatile String foo;
public String getFoo() {
return foo;
}
public void setFoo(String in) {
this.foo = in;
}
volatile solves 3 problems 1) memory visibility 2) atomic writes for double and long fields 3) forbids instructions reordering. But it's not enough if you need several operations over a field as one atomic transaction, such as increment. This code is broken
private volatile int id;
public void incrementId() {
id++;
}
because if 2 threads simulataneously read and increment it and save the result then the result of the first increment will be overwritten with the result of the second increment. To prevent this from happening we need to use synchronization
private int id;
public synchronized int nextId() {
return ++id;
}
or java.util.concurrent.atomic package
private AtomicInteger id = new AtomicInteger();
public void incrementId() {
return id.incrementAndGet();
}
If all you are doing is setting foo, then you don't need to synchronize the method. making the reference volatile is sufficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With