编程语言
首页 > 编程语言> > 深入了解Java中的volatile

深入了解Java中的volatile

作者:互联网

Java是否允许输出1、0?我已经对其进行了非常深入的测试,但无法获得该输出.我只会得到1、1或0、0或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是易失性的,因此将确保内存顺序.因此,它看起来像:

actor1:

(1) store(x, 1)
(2) store(g, 1)
(3) memory_barrier // on x86

而且,我看到以下情况:
在store(x,1)之前对store(g,1)重新排序(memory_barrier在(2)之后).
现在,运行线程2.因此,g = 1,x =0.现在,我们有了预期的输出.
我的推理有何不正确之处?

解决方法:

易失性写入之前的任何操作都发生在(HB)同一变量的任何后续易失性读取之前.在您的情况下,对x的写入发生在对g的写入之前(由于程序顺序).

因此,只有三种可能性:

> actor2首先运行,并且x和g为0-输出为0,0
> actor1首先运行,并且x和g为1,因为发生在关系HB之前-输出为1,1
>这些方法并发运行,并且仅执行x = 1(不执行g = 1),并且输出可以为0,1或0,0(无易失性写,因此无法保证)

标签:memory-barriers,java
来源: https://codeday.me/bug/20191025/1931798.html