volatile关键字
1.多线程内存模型

2.做个小的测试
public class VolatileTest implements Runnable {
//当为false时线程结束
private static /*volatile*/ boolean flag = true;
private static int value = 100;
@Override
public void run() {
// TODO Auto-generated method stub
while(flag) {
value++;
//System.out.println(value);//可以取消注释试一试
}
System.out.println(value);
}
public static void main(String[] args) throws InterruptedException {
new Thread(new VolatileTest() ).start();
Thread.sleep(1000);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
flag = false;
}
}).start();
Thread.sleep(1000);
System.out.println(flag);
}
}
我们可以发现,第二个线程将flag改成false,但是第一个线程并没有停止运行.所以我们可以得出结论:
两个线程的flag不是同一个,改变一个线程的flag不会引起另一个线程flag变化,所以循环不会结束.
3.为什么?
从第一幅图我们可以看出,各一个线程都有一个工作内存,线程运行时,他会从主内存读取数据到工作内存,然后在使用工作内存,执行完在save到工作内存.但是其他线程感知不到主内存的变化,不知道主内存的flag变成了false,所以没有更新自己的工作空间中的flag(因为没有操作让他去主内存读取数据),导致flag为true,所以循环无法终止.
4.volatile的作用
当我们在flag前添加volatile关键字后发现,程序可以跳出循环.
volatile关键字:强制让其读取主内存,而不是工作空间,多个线程使用的为同一个空间,就保证了可见性.
latile关键字:强制让其读取主内存,而不是工作空间,多个线程使用的为同一个空间,就保证了可见性.
5.volatile保证了可见性但是却没有保证原子性.需要其他操作来实现.
来源:CSDN
作者:qq_29303419
链接:https://blog.csdn.net/qq_29303419/article/details/103455919