Is there any reason to use volatile and synchronized together in this code?
public class Helper {
private volatile int n;
private final Object lock = new Object();
public Helper(int n) {
this.n = n;
}
public void setN(int value) {
synchronized (lock) {
n = value;
}
}
}
Class Helper must be thread safe. I've got this example from the "Java Concurrency Guidelines" book, but it is still not clear: what is the reason for using volatile and synchronized together in this example?
If it is accessed only from synchronized blocks is not needed the volatile keyword. Synchronized guarantees that changes to variables accessed inside the synchronized block are visible to all threads entering a synchronized block.
Effectively, a variable declared volatile must have it's data synchronized across all threads, so that whenever you access or update the variable in any thread, all other threads immediately see the same value. Generally volatile variables have a higher access and update overhead than "plain" variables.
We may use the synchronized keyword for maintaining thread safety. However, the volatile keyword is essentially lock-free and hence the most lightweight means of providing thread safety. Declaring a Volatile Variable Simply Means: The value of this variable will never be cached in the threads' caches locally.
You can have both static synchronized method and nonstatic synchronized method and synchronized blocks in Java but we can not have synchronized variable in java. Using synchronized keyword with a variable is illegal and will result in compilation error.
The purpose of this example is to point out that syncronized
without volatile
isn't enough in this case given the fact that object can be published unsafely (i.e. without volatile
in Foo
):
If the helper field in the Foo class is not declared volatile, the n field should be declared volatile so that a happens-before relationship is established between the initialization of n and the write of Helper to the helper field. This is in compliance with guideline “VNA06-J. Do not assume that declaring an object reference volatile guarantees visibility of its members” on page 35. This is required only when the caller (class Foo) cannot be trusted to declare helper volatile.
That's correct, but they chose a bad example to demonstrate it, because volatile
without syncrhonization is enough in this case.
It's not necessary to put the synchronised block around the change in value; since Java 5 this is done "automatically" for volatile variables. I think that previous to Java 5, it was not necessarily the case.
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