问题
I read following about volatile
from the book Java Concurrency in Practice:
When a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations. Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread.
The visibility effects of volatile variables extend beyond the value of the volatile variable itself. When thread A writes to a volatile variable and subsequently thread B reads that same variable, the values of all variables that were visible to A prior to writing to the volatile variable become visible to B after reading the volatile variable. So from a memory visibility perspective, writing a volatile variable is like exiting a synchronized block and reading a volatile variable is like entering a synchronized block.
I am confused with the last sentence above. Say variable x
is defined volatile
and before modifying x
, u
,v
and w
were visible to thread A
, then when thread B
reads x
afterwards, it will also be able to read latest values of u
,v
and w
. Can we specify for same for synchronized
?.
Q1. That is, is below correct?
Variables
u
,v
andw
were visible to threadA
while exitingsynchronized
block, then the latest values ofu
,v
andw
will be visible to threadB
enteringsynchronized
block afterwards.
I feel above fact is incorrect as u
,v
and w
may be stored in caches and registers as they are not defined volatile
. Am I correct with this? So visibility is not ensured by synchronized
(and also by locks
and atomic
variables as they are similar to synchronized
)
The book further says:
Locking can guarantee both visibility and atomicity; volatile variables can only guarantee visibility.
But I feel following:
- Locks,
synchronized
and atomic variables only guarantee read-write atomicity (not visibility and protection from reordering). volatile
guarantee visibility and protection from reordering by compiler and runtime (not read-write atomicity).
Q2. Am I correct with above two points?
回答1:
1) Locks, synchronized and atomic variables guarantee read-write atomicity and visibility and protection from reordering
2) volatile guarantees visibility and protection from reordering by compiler and runtime
read-write atomicity of volatile fields is a little bit tricky: reading and writing to a volatile field is atomic, for example if you write to a volatile long (64 bit) on a 32 bit jvm the read and the write is still atomic. You always read the complete 64 bit. But operations like ++ on a volatile int or long are not atomic
来源:https://stackoverflow.com/questions/60931421/lock-vs-synchronized-vs-atomic-variables-vs-volatile-in-java-in-terms-of-read-wr