文档章节

volatile与可见性

w
 wall--e
发布于 2016/05/08 22:45
字数 521
阅读 163
收藏 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
粉丝 5
博文 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

没有更多内容

加载失败,请刷新页面

加载更多

Spring的Resttemplate发送带header的post请求

private HttpHeaders getJsonHeader() { HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); ......

qiang123
昨天
0
0
Spring Cloud Gateway 之 Only one connection receive subscriber allowed

都说Spring Cloud Gateway好,我也来试试,可是配置了总是报下面这个错误: java.lang.IllegalStateException: Only one connection receive subscriber allowed. 困扰了我几天的问题,原来...

ThinkGem
昨天
5
0
学习设计模式——观察者模式

1. 认识观察者模式 1. 定义:定义对象之间一种一对多的依赖关系,当一个对象状态发生变化时,依赖该对象的其他对象都会得到通知并进行相应的变化。 2. 组织结构: Subject:目标对象类,会被...

江左煤郎
昨天
0
0
emoji

前言:随着iOS系统版本的升级,对原生emoji表情的支持也越来越丰富。emoji表情是unicode码中为表情符号设计的一组编码,当然,还有独立于unicode的另一套编码SBUnicode,在OS系统中,这两种编...

HeroHY
昨天
2
0
rabbitmq学习(二)

生产者消费者初级案列 ChannelUtils package com.hensemlee.rabbitmq;import com.rabbitmq.client.Channel;import com.rabbitmq.client.Connection;import com.rabbitmq.client.Connecti......

hensemlee
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部