s7vr
s7vr

Reputation: 75934

Can synchronized read be replaced with volatile field modifier?

While reading the accepted answer How to synchronize or lock upon variables in Java?, it occurred to me if the behavior would change if one was to use volatile in the below example instead of synchronized block. I would like to make sure message always return the correct value.

Let me use this same sample: Note now I've removed the synchronized block in the get method and marked the variable message as volatile.

class Sample {
    private volatile String message = null;
    private final Object lock = new Object();

    public void newMessage(String x) {
        synchronized (lock) {
            message = x;
        }
    }

    public String getMessage() {
            return message;
        }
    }
}

Would it warrant the same behavior if one was to change the code as shown above ?. Are there any differences between two approaches ?

Thank you in advance

Upvotes: 2

Views: 2694

Answers (1)

Eric
Eric

Reputation: 936

The volatile keyword in this case is enough because it establishes a happens-before relation for the reads and writes, guaranteeing that the write in one thread will be observed by a subsequent read in another thread.

The synchronized block is not incorrect but it is redundant. Also, if you do use synchronized, you can mark your message variable as non-volatile. But be careful and make sure the read is also in a synchronized block, otherwise you have a data race. Non-volatile writes made by one thread in a synchronized block are guaranteed to be visible for threads subsequently entering a synchronized block on the same monitor.

As a final note, the synchronized block has different progress conditions than volatile reads and writes. The former is blocking (mutual exclusion) while the latter is wait-free.

Upvotes: 1

Related Questions