问题描述
我从《 Java并发实践》一书中阅读了有关volatile
的以下内容:
I read following about volatile
from the book Java Concurrency in Practice:
易失性变量的可见性影响超出了易失性变量本身的值.当线程A写入易失性变量,随后线程B读取相同的变量时,在读取易失性变量后,在写入易失性变量之前A可见的所有变量的值对B都是可见的.因此,从内存可见性的角度来看,写入volatile变量就像退出同步块,而读取volatile变量就像进入同步块.
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.
我对上面的最后一句话感到困惑.假设变量x
被定义为volatile
,并且在修改x
,u
,v
和w
对线程A
可见之前,然后当线程B
之后读取x
时,它将还可以读取u
,v
和w
的最新值.我们可以为synchronized
指定相同的名称吗?
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
?.
第1季度.也就是说,下面的答案正确吗?
Q1. That is, is below correct?
我觉得上述事实是不正确的,因为u
,v
和w
可能存储在缓存和寄存器中,因为它们没有定义为volatile
.我对此正确吗?因此synchronized
(以及locks
和atomic
变量也不能保证可见性,因为它们与synchronized
相似)
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
)
这本书进一步说:
但是我有以下感受:
- 锁,
synchronized
和原子变量仅保证读写原子性(不保证可见性和防止重新排序). -
volatile
保证可见性并防止编译器和运行时对其进行重新排序(不是读写原子性).
- 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 andvisibility and protection from reordering
2)volatile保证可见性并防止编译器和运行时重新排序
2) volatile guarantees visibility and protection from reordering by compiler and runtime
易失性字段的读写原子性有些棘手:对易失性字段的读写是原子性的,例如,如果您在32位jvm上对易失性long(64位)进行写操作,则读和写操作为仍然是原子的.您总是会阅读完整的64位.但是像volatile int或long这样的操作不是原子
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
这篇关于在读写原子性,可见性和防止重新排序方面,Java中的锁,同步,原子变量和易失性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!