我很困惑,是不是真的很有用?

时间:2014-03-26 01:37:36

标签: java volatile

我写了一个试图理解volatile的例子。

public class VolatileExample {

private volatile boolean close = false;

public void shutdown() {
    close = true;
}

public void work(){

    Thread t1 = new Thread(new Runnable(){
        public void run(){
            while (!close) {

            }
        }
    });

    Thread t2 = new Thread(new Runnable(){
        public void run(){
            while (!close) {
                shutdown();
            }
        }
    });

    t1.start();
    t2.start();
    try {
        t1.join();
        t2.join();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }   
}

public static void main(String[] args){
    VolatileExample volatileExample = new VolatileExample();
    volatileExample.work();
}   
}
它确实像我预期的那样停了下来。 然而,当我从volatile标签中取出volatile时,我已经尝试了很多次 - 我希望程序不会停止,因为线程t1无法看到线程t2对close变量所做的更改,但程序每次都成功结束。所以我很困惑,现在我们可以做到没有不稳定,什么是挥发性的?或者你能举出一个更好的例子来说明使用volatile和不使用volatile吗?

谢谢!

2 个答案:

答案 0 :(得分:7)

内存模型只表示对非易失性字段的更改可能在其他线程中不可见。

也许您的运行时环境处于合作氛围中。

答案 1 :(得分:1)

非易失性字段的更改有时对其他线程可见,有时则不可见。根据机器正在进行的其他处理,机器上的处理器芯片和内核的数量,机器上的高速缓冲存储器的体系结构等,它们对其他线程可见多长时间可以根据数量级而变化。 / p>

最终,它归结为:错误的并发代码可以在前999,999次成功,并在第一百万次失败。这通常意味着它通过了所有测试,然后在生产真正重要时生产失败。出于这个原因,在编写并发代码时,最重要的是确保代码是正确的 - 这意味着对于从多个线程访问的变量使用volatile,即使它似乎没有测试的差异。