我写了一个试图理解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吗?
谢谢!
答案 0 :(得分:7)
内存模型只表示对非易失性字段的更改可能在其他线程中不可见。
也许您的运行时环境处于合作氛围中。
答案 1 :(得分:1)
非易失性字段的更改有时对其他线程可见,有时则不可见。根据机器正在进行的其他处理,机器上的处理器芯片和内核的数量,机器上的高速缓冲存储器的体系结构等,它们对其他线程可见多长时间可以根据数量级而变化。 / p>
最终,它归结为:错误的并发代码可以在前999,999次成功,并在第一百万次失败。这通常意味着它通过了所有测试,然后在生产真正重要时生产失败。出于这个原因,在编写并发代码时,最重要的是确保代码是正确的 - 这意味着对于从多个线程访问的变量使用volatile,即使它似乎没有测试的差异。