Knowing that
Reads and writes are atomic for all variables declared volatile
Question1: Can this be understood as if
private volatile int x = 0;
x++;
operation is atomic?
And that
Marking variable volatile does not eliminate all need to synchronize atomic actions, because memory consistency errors are still possible.
Question2: I wonder under what circumstances (if any) it is possible to see a variable marked volatile
and not see any methods of blocks marked synchronized (that attempt to access/ modify the variable)?
In other words, should all variables that need to be protected from concurrent modification be marked volatile
?
The volatile only gives you additional visibility guarantees, atomic writes/reads for longs/doubles (otherwise not guaranteed by the JLS, yes) and some memory order guarantees. No synchronization (it is possible though to build synchronization blocks starting with just volatile - Dekker's algorithm )
So no, it does not help you with x++
- that's still a read, inc and write and needs some form of synchronization.
One example of volatile is the famous double-checked locking, where we avoid synchronization most of the time because the ordering guarantees are all we need:
private volatile Helper helper = null;
public Helper getHelper() {
if (helper == null) {
synchronized(this) {
if (helper == null) {
helper = new Helper();
}
}
}
return helper;
}
An example where there's absolutely no synchronization involved, is a simple exit flag, here it's not about ordering guarantees but only about the guaranteed visibility
public volatile boolean exit = false;
public void run() {
while (!exit) doStuff();
// exit when exit set to true
}
If another thread sets exit = true
the other thread doing the while loop is guaranteed to see the update - without volatile it may not.
x++; operation is atomic?
No. This reduces to x = x + 1
. The read of x
is atomic, and the write to x
is atomic, but x = x + 1
as a whole is not atomic.
I wonder under what circumstances (if any) it is possible to see a variable marked volatile and not see any methods of blocks marked synchronized (that attempt to access/ modify the variable)?
Well, there are all kinds of approaches to concurrency that don't use synchronized
. There's a wide variety of other locking utilities in Java, and lock-free algorithms that still require things like volatile
: ConcurrentLinkedQueue
is a specific example, though it makes extensive use of "magical" compareAndSet
atomics.
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