Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronize write access to Volatile field (Cheap read-write block)

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.

like image 442
oberger Avatar asked Mar 05 '13 01:03

oberger


2 Answers

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();
 }
like image 186
Evgeniy Dorofeev Avatar answered Oct 12 '22 01:10

Evgeniy Dorofeev


If all you are doing is setting foo, then you don't need to synchronize the method. making the reference volatile is sufficient.

like image 31
jtahlborn Avatar answered Oct 12 '22 02:10

jtahlborn