为什么这段代码没有易失性?

时间:2015-06-20 16:41:35

标签: java

我是Java的新手,我目前正在学习volatile。说我有以下代码:

public class Test
{
    private static boolean b = false;

    public static void main(String[] args) throws Exception
    {
        new Thread(new Runnable()
        {
            public void run()
            {
                while(true) 
                {
                    b = true;   
                }
            }
        }).start();

        // Give time for thread to start
        Thread.sleep(2000);

        System.out.println(b);
    }
}

输出:

  

此代码有两个线程(主线程和另一个线程)。为什么另一个帖子能够修改b的值,b不应该volatile才能发生这种情况?

2 个答案:

答案 0 :(得分:3)

volatile关键字保证在多个线程中可以看到更改,但是您将其解释为意味着相反也是如此;缺少volatile关键字可以保证线程之间的隔离,并且没有这样的保证。

此外,虽然您的代码示例是多线程的,但它不一定是并发的。可能是每个线程都缓存了值,但是在打印结果之前,JVM有足够的时间传播更改。

答案 1 :(得分:1)

对于volatile,你是对的,你可以确保/保证你的2个线程将始终从主内存中看到适当的值,而不是特定于线程的缓存版本。

没有volatile,你就失去了保证。每个线程都使用自己的缓存版本的值。

然而,没有什么能阻止2个线程在他们想要的时候重新同步他们的内存,并最终查看相同的值(可能)。只是因为你无法保证会发生这种情况,而且当你 发生时,你肯定无法保证 。但 可以 在某个不确定的时间点发生。

重点是您的代码有时可能有效,有时则无效。但即使每次在个人计算机上运行它,似乎它正确地读取变量,很可能这个相同的代码会在另一台机器上运行。所以你冒了很大的风险。