Suppose I have a instance variable and I have setters and getters.
Code 1:
Class<T> {
volatile T value;
public synchronized void set(T v) {
if(value==null) {
value=v;
}
}
public T get() {
return value;
}
}
Code 2:
Class<T> {
static volatile T value;
public synchronized void set(T v) {
if(value==null) {
value=v;
}
}
public T get() {
return value;
}
}
I have two questions
1) What is the difference having static volatile state field and only volatile state field?
2) I just came to know about release / acquire concept of volatile read/write and understood that there is no need to synchronize the getter(because of cache flush).But is there any need to synchronize the setter?
Let's start with your second question:
I think the reason why you schould use a synchronized block in your setter is that you perform two different operations on value
. You check value==null
and afterwards you set value=v
. While you do have the lock in each step you don't have it between them. So this is possible:
Thread1: lock value -> value==null (true) -> release value
Thread2: lock value -> value==null (true) -> release value
Thread1: lock value -> value=v -> release value;
Thread2: lock value -> value=v -> release value;
So you still have a race condition.
Now back to your first question: You schould use static to have any instance of your class use the same variable T instead of having an own one.