I dont understand those few statements that I read:
because accessing a volatile variable never holds a lock, it is not suitable for cases where we want to read-update-write as an atomic operation (unless we're prepared to "miss an update");
What does it mean, I cant read-update-write?
When will I want to use volatile instead of simple boolean. In C#, I remember that I could use a simple static bool to control when a thread starts and stops, but in java I need to use the identifier, "volatile":
> public class StoppableTask extends Thread {
private volatile boolean pleaseStop;
public void run() {
while (!pleaseStop) {
// do some stuff...
}
}
public void tellMeToStop() {
pleaseS开发者_Python百科top = true;
}
}
The sentence speaks about this example:
public class CounterClass {
private volatile int counter;
public int increment() {
return counter++;
}
}
Although the counter
has volatile
modifier, it is not guaranteed that if two threads access the increment()
method that two different integers will be returned. Because the counter++
operation is not atomic. It is get, increment, return
. It is possible that two threads call increment()
at the same time and that the first thread is at the get
phase and the second thread is at the get
phase before the first thread is at the increment
phase.
Summary: volatile
doesn't guarantee atomicity or whatever. It just guarantees that when you access the variable, you will not receive an old cached value. But it doesn't guarantee any thread safety or atomicity.
When will I want to use volatile
FWIW Brian Goetz in Managing volatility lists five patterns for using volatile:
- status flags ("canonical")
- one-time safe publication
- independent observations ("an extension of the previous one")
- the "volatile bean" pattern
- the cheap read-write lock trick ("if reads greatly outnumber modifications")
BTW this image has helped me to figure memory guarantees for volatile:
Above,
ready
is volatile. Note whatever guarantees are there, these are only for assignment, not for read-update-write
- Above image is taken from Jeremy Manson's blog article: What Volatile Means in Java.
"The first thread writes to
ready
, which is going to be the sender side of the communications. The second thread reads from ready and sees the value the first thread wrote to it. It therefore becomes a receiver. Because this communication occurs, all of the memory contents seen by Thread 1, before it wrote to ready, must be visible to Thread 2, after it reads the value true for ready."
精彩评论