多线程-volatile

孤人 提交于 2019-12-10 06:28:46

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保证了可见性但是却没有保证原子性.需要其他操作来实现.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!