深入理解Java中的volatile [英] Deep understanding of volatile in Java

查看:169
本文介绍了深入理解Java中的volatile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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)之前重新订购 store(g,1) (memory_barrier (2)之后)。
现在,运行线程#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 (not g=1) and the output could be either 0,1 or 0,0 (no volatile write so no guarantee)

这篇关于深入理解Java中的volatile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆