是在Java中写入易失性的内存屏障

我最近在一次演讲中听到,写入volatile会触发线程写入的每个变量的内存屏障。 这是真的正确吗? 从JLS看来,似乎只有相关变量才会被刷新,而其他变量则不然。 有人知道什么是正确的吗? 能指出我在JLS的具体位置吗?

是的,它会引发障碍。 你可以在这里阅读更多。 LoadLoad LoadStore StoreStore StoreLoad有4种类型。

至于你的问题

从JLS看来,似乎只有相关变量才会被刷新,而其他变量则不然。 有人知道什么是正确的吗?

在易失性存储之前发生的所有写入都可由任何其他线程看到,其他线程加载此新存储的谓词。 但是,如果未加载新值,则在易失性加载之前发生的写入可能会或可能不会被其他线程看到。

一个实际的例子

volatile int a =0; int b = 0; Thread-1 b = 10; a = 3; Thread-2 if(a == 0){ // b can b 10 or 0 } if(a == 3){ // b is guaranteed to be 10 (according to the JMM) } 

对易失性变量和其他变量的引用是正确的。 我没有意识到发生之前的传递性是必须由VM实现的东西,而不是定义后面的东西。 我仍然感到困惑的是,为什么具有如此深远影响的事情没有明确说明,但实际上是某种定义的必然结果。 包装起来:假设你有4个这样的动作:

 thread1 thread2 a1 a2 a3 a4 

其中a2是对易失性变量v的写入,而a3是从相同的易变量v中读取的。它来自于发生之前(hb)hb(a1,a2)和hb(a3,a4)的定义。 此外,对于挥发物,我们有hb(a2,a3)。 现在来自hb所需的传递性hb(a1,a3)。 因此,易失性变量v的写入和后续读取用作存储器屏障。