MKK*_*MKK 22 java concurrency volatile jls
我最近在一次演讲中听到,写入volatile会触发线程写入的每个变量的内存屏障.这是真的正确吗?从JLS看来,似乎只有相关的变量才被刷新,而其他变量则没有.有人知道什么是正确的吗?能指出我在JLS的具体位置吗?
Joh*_*int 22
是的,它会引发障碍.你可以在这里阅读更多.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)
}
Run Code Online (Sandbox Code Playgroud)
对挥发性变量和其他变量的引用是正确的。我没有意识到happens-before的传递性是VM必须实现的东西,而不是从定义中得出的东西。我仍然感到困惑,为什么具有如此深远影响的事情没有明确说明,而实际上是某种定义的推论。总结一下:假设您有 4 个这样的操作:
thread1 thread2
a1
a2
a3
a4
Run Code Online (Sandbox Code Playgroud)
其中a2是对易失性变量v的写入,a3是对同一个易失性变量v的读取。根据happens-before (hb)的定义可以得出hb(a1,a2)和hb(a3,a4)。另外,对于挥发物,我们有 hb(a2,a3)。现在根据 hb 所需的传递性得出 hb(a1,a3)。因此,易失性变量 v 的写入和后续读取起到了内存屏障的作用。
归档时间: |
|
查看次数: |
5644 次 |
最近记录: |