Reputation: 75934
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
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