首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >变量的易失性写入是否避免了无序写入?

变量的易失性写入是否避免了无序写入?
EN

Stack Overflow用户
提问于 2014-05-05 10:59:52
回答 1查看 190关注 0票数 0

易失性写入是否确保在一个线程中发生的任何写入(非易失性/易失性写入)对其他线程都是可见的?

以下给定的代码是否总是生成90,80作为输出?

代码语言:javascript
复制
public class MyClass
{
    private boolean flag = false;
    private volatile int volatileInt = 0;
    private int nonVolatileInt = 0;
    public void initVariables()
    {
        nonVolatileInt = 90; // non-volatile write
        volatileInt = 80; // volatile write
        flag = true; // non-volatile write
    }
    public void readVariables()
    {
        while (flag == false)
        {}
        System.out.println(nonVolatileInt + ","+ volatileInt);
    }
    public static void main(String st[])
    {
        final MyClass myClass = new MyClass();
        Thread writer = new Thread( new Runnable()
        {
            public void run()
            {
                myClass.initVariables();
            }
        });
        Thread reader = new Thread ( new Runnable()
        {
            public void run()
            {
                myClass.readVariables();
            }
        });
        reader.start();writer.start();
    }
}

我关心的是initVariables()方法。JVM不是可以自由地以以下方式重新排序代码块吗?

代码语言:javascript
复制
flag = true;
nonVolatileInt = 90 ; 
volatileInt = 80;

因此,我们将读取器线程的输出作为:0,0

或者,它们可以按以下方式重新排序:

代码语言:javascript
复制
nonVolatieInt = 90;
flag = true;
volatileInt = 80;

因此,我们将读取器线程的输出作为:90,0

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-05-05 11:04:19

易失性写入确保已执行的写入不会在此写入之后出现。但是,为了确保您看到了这一点,您需要首先执行易失性读取。

因此,我们将读取器线程的输出作为:90,0

对,是这样。但是,如果正确执行读取操作,则无法获得0, 80

代码语言:javascript
复制
0, 0 - ok
90, 0 - ok
90, 80 - ok
0, 80 - breaks happens before.

但是,您的读取不能确保在行为之前发生,因为它不会首先执行易失性读取。

代码语言:javascript
复制
System.out.println(nonVolatileInt + ","+ volatileInt);

这首先读取非易失性字段,因此您可以看到非易失性字段的旧版本和易失性字段的新版本。

注意:实际上,你不太可能看到问题。这是因为缓存一次使整个缓存行失效,如果这些字段位于相同的64字节块中,则不应该看到不一致。

更有可能成为问题的是这个循环。

代码语言:javascript
复制
 while (flag == false)
    {}

问题是,JIT可以看到线程嵌套写入flag,因此它可以内联该值。也就是说,它不需要读取值。这可能导致无限循环。

http://vanillajava.blogspot.co.uk/2012/01/demonstrating-when-volatile-is-required.html

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23470842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档