Answer by Kerem Baydoğan is completely right. I just want to give an practical example about what volatile
keyword offers us.
First, we have a counter, smth like
public class Counter {
private int x;
public int getX() { return x; }
public void increment() { x++; }
}
And some Runnable tasks which increments the value of x
@Override
public void run() {
for (N) {
int oldValue = counter.getX();
counter.increment();
int new value = counter.getX();
}
}
}
With NO synchronization there is going to be interference between threads and simply is not going to work
the simplest way to solve this:
public class Counter {
private int x;
public synchronized int getX() { return x; }
public synchronized void increment() { x++; }
}
Actually in order to force the system to break, I do a Thread.sleep
before reading and writing x
, just imagine is a BD or a huge task to deal with.
Now, what is volatile
useful for? There are a lot of good articles over there: volatile article or this question
synchronizing the access to the common resource is not the answer but is a good choice to hold the flag to stop threads
I our prev. example, imagine we want to increment the variable up to 100, a simply way could be a volatile boolean
flag. Example:
private volatile boolean stop;
@Override
public void run() {
while(!stop) {
int oldValue = counter.getX();
if (oldValue == 100) {
stop = true;
} else {
counter.increment();
int new value = counter.getX();
}
}
}
This works fine, but, if you remove the volatile
keyword from the flag, it's possible to come across and infinite loop.