深入理解Java中的volatile [英] Deep understanding of volatile in Java
问题描述
Java是否允许输出 1,0
?我已经对它进行了非常密集的测试,但我无法获得该输出。我只得到 1,1
或 0,0
或 0,1
。
Does Java allows output 1, 0
? I've tested it very intensively and I cannot get that output. I get only 1, 1
or 0, 0
or 0, 1
.
public class Main {
private int x;
private volatile int g;
// Executed by thread #1
public void actor1(){
x = 1;
g = 1;
}
// Executed by thread #2
public void actor2(){
put_on_screen_without_sync(g);
put_on_screen_without_sync(x);
}
}
为什么?
在我看来,可以获得 1,0
。我的理由。
g
是易失性的,因此会确保内存顺序。所以看起来像:
On my eye it is possible to get 1, 0
. My reasoning.
g
is volatile so it causes that memory order will be ensured. So, it looks like:
actor1:
(1) store(x, 1)
(2) store(g, 1)
(3) memory_barrier // on x86
并且,我看到以下情况:
在 store(x,1)之前重新订购
(memory_barrier (2)之后)。 store(g,1)
现在,运行线程#2。所以, g = 1,x = 0
。现在,我们已经预期了产量。
我的推理有什么不对?
and, I see the following situation:
reorder store(g, 1)
before store(x,1)
(memory_barrier is after (2)).
Now, run thread #2. So, g = 1, x = 0
. Now, we have expected output.
What is incorrect in my reasoning?
推荐答案
易失性写入之前的任何操作发生在(HB)同一变量的任何后续易失性读取之前。在您的情况下,写入 x
发生在写入 g
之前(由于程序顺序)。
Any actions before a volatile write happen before (HB) any subsequent volatile read of the same variable. In your case, the write to x
happens before the write to g
(due to program order).
因此只有三种可能性:
- actor2首先运行,x和g为0 - 输出为0,0
- actor1首先运行,x和g为1,因为在关系HB之前发生 - 输出为1,1
- 方法并发运行,只执行
x = 1
(不是g = 1
),输出可能为0 ,1或0,0(没有易失性写,所以不保证)
- actor2 runs first and x and g are 0 - output is 0,0
- actor1 runs first and x and g are 1 because of the happens before relationship HB - output is 1,1
- the methods run concurrently and only
x=1
is executed (notg=1
) and the output could be either 0,1 or 0,0 (no volatile write so no guarantee)
这篇关于深入理解Java中的volatile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!