volatile与可见性
博客专区 > wall--e 的博客 > 博客详情
volatile与可见性
wall--e 发表于2年前
volatile与可见性
  • 发表于 2年前
  • 阅读 154
  • 收藏 3
  • 点赞 2
  • 评论 0

新睿云服务器60天免费使用,快来体验!>>>   

摘要: 何为可见性? 下面是两段很诡异的代码, 根本原因在于可见性, 如何用 volatile 关键字实现可见性,

可见性

    一句话概括可见性

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

 

下面通过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 可以实现可见性

 

其他实现可见性的方式

  • 打赏
  • 点赞
  • 收藏
  • 分享
共有 人打赏支持
粉丝 4
博文 31
码字总数 25016
×
wall--e
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: