文档章节

volatile与可见性

w
 wall--e
发布于 2016/05/08 22:45
字数 521
阅读 161
收藏 3

可见性

    一句话概括可见性

    一个线程修改了共享变量, 其他线程可以立即知道

 

下面通过2段代码, 看一看 volatile 的作用:

1. 未经 volatile 修饰的共享变量 stop

/**
 * @author 宋挺
 */
public class VolatileDemo1 implements Runnable {
	// 共享变量
	private boolean stop = false;

	// 修改共享变量
	public void stop() {
		this.stop = true;
	}

	// 线程体
	@Override
	public void run() {
		while (!stop) {
		}
		System.out.println("子程序 stoped");
	}

	public static void main(String[] args) throws InterruptedException {
		VolatileDemo1 vd = new VolatileDemo1();
		// 新建态
		Thread subThread = new Thread(vd);
		// 就绪态
		subThread.start();
		// 在主线程调用 stop() 方法之前, 保证子线程先启动, 进入运行状态
		Thread.sleep(10);
		// 主线程调用 stop() 方法, 将共享变量 stop 修改为 true
		vd.setStop();
	}
}

 

运行这段代码时, 可以发现:

无输出

这说明子线程 subThread 的 run() 方法一直处于死循环中, stop 值为 false, 但是明明在主线程修改了 stop 为 true 啊

这是因为在主线程只是在其工作内存修改了共享变量的副本, 而主内存的共享变量没有被及时更新, 所以其他线程观察不到这个修改动作

 

2. 用 volatile 修饰共享变量 stop

/**
 * @author 宋挺
 */
public class VolatileDemo1 implements Runnable {
	// 用 volatile 修饰共享变量
	private volatile boolean stop = false;

	// 修改共享变量
	public void stop() {
		this.stop = true;
	}

	// 线程体
	@Override
	public void run() {
		while (!stop) {
		}
		System.out.println("子程序 stoped");
	}

	public static void main(String[] args) throws InterruptedException {
		VolatileDemo1 vd = new VolatileDemo1();
		// 新建态
		Thread subThread = new Thread(vd);
		// 就绪态
		subThread.start();
		// 在主线程调用 stop() 方法之前, 保证子线程先启动, 进入运行状态
		Thread.sleep(10);
		// 主线程调用 stop() 方法, 将共享变量 stop 修改为 true
		vd.setStop();
	}
}

 

运行这段代码时, 可以发现:

    输出: 子程序 stoped

这说明主线程在修改共享变量后, 子线程在工作内存中更新了共享变量的最新值

由此可见, volatile 可以实现可见性

 

其他实现可见性的方式

© 著作权归作者所有

共有 人打赏支持
w
粉丝 4
博文 31
码字总数 25016
作品 0
东城
程序员
Java多线程之内存可见性

Java内存模型( JMM ) : 1) 所有的变量都存储在主内存中 2) 每个线程都有自己独立的工作内存, 里面保存该线程使用到的变量的副本 ( 主内存中该变量的一份拷贝 ) JMM 两条规定: 1) 线程对共享变...

wall--e
2016/05/07
174
1
volatile关键字解析~高级java必问

昨天我介绍了原子性、可见性、有序性的概念,那么今天就来见识下这些概念的主角-volatile关键字。 volatile基本介绍 volatile可以看成是synchronized的一种轻量级的实现,但volatile并不能完...

java技术栈
2017/08/13
0
0
多线程学习笔记(十二)

volatile的作用是使变量在多个线程间可见 1.死循环 public class PrintInfo implements Runnable { } public class Run { PrintInfo printInfo = new PrintInfo();printInfo.printInfo();Sy......

scymore
2016/09/13
43
0
Java并发编程笔记2-线程可见性&线程封闭&指令重排序

一.指令重排序 例子如下: public class Visibility1 { } public class ReaderThread extends Thread { } public class Test1 { } 多次运行结果分别如下: 可以看到多次运行所得到三种结果,...

狂小白
03/05
0
0
并发和多线程-说说面试常考平时少用的volatile

说到volatile,一些参加过面试的同学对此肯定不陌生。 它是面试官口中的常客,但是平时的编码却很少打照面(起码,我是这样的)。 最近的面试,我也经常会问到volatile相关的问题,比如volat...

Jackie_Zheng
06/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

7 个致命的 Linux 命令

导读 如果你是一个 Linux 新手,在好奇心的驱使下,可能会去尝试从各个渠道获得的命令。以下是 7 个致命的 Linux 命令,轻则使你的数据造成丢失,重则使你的系统造成瘫痪,所以,你应当竭力避...

问题终结者
今天
0
0
设计模式:工厂方法模式(工厂模式)

工厂方法模式才是真正的工厂模式,前面讲到的静态工厂模式实际上不能说是一种真正意义上的设计模式,只是一种变成习惯。 工厂方法的类图: 这里面涉及到四个种类: 1、抽象产品: Product 2、...

京一
今天
0
0
区块链和数据库,技术到底有何区别?

关于数据库和区块链,总会有很多的困惑。区块链其实是一种数据库,因为他是数字账本,并且在区块的数据结构上存储信息。数据库中存储信息的结构被称为表格。但是,区块链是数据库,数据库可不...

HiBlock
今天
0
0
react native 开发碰到的问题

react-navigation v2 问题 问题: static navigationOptions = ({navigation, navigationOptions}) => ({ headerTitle: ( <Text style={{color:"#fff"}}>我的</Text> ), headerRight: ( <View......

罗培海
今天
0
0
Mac Docker安装流程

久仰Docker大名已久,于是今天趁着有空,尝试了一下Docker 先是从docker的官网上下载下来mac版本的docker安装包,安装很简易,就直接拖图标就好了。 https://www.docker.com/products/docker...

writeademo
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部