volatile关键字的理解
volatile是java语言提供的一种稍弱的同步机制,它的作用是能够保证被volatile修饰的变量,每个线程在获取它的值时都能获取到最新的值。
要理解这个原理首先要知道java内存模型:每个线程都有自己的工作内存,线程对变量的所有操作都必须在工作内存中进行 。每个线程都会将运算需要的数据从主内存复制一份到自己的工作内存,等运算结束之后才会刷新到主内存中。
理解了上述模型,就会发现在并发情况下可能会出现数据不一致的现象,例如线程1和线程2同时从主内存中复制了一个变量a=1到自己的工作内存,但是期间线程1先对a进行了操作将值改为2,之后线程2中仍然按照a等于旧值1进行运算,这显然会出现问题。
于是有了volatile关键字:当一个线程改变了某个变量的值,就会通知其他线程:你们的缓冲区(工作内存)中变量的值已经发生改变了,请重新从主内存中读取新的值。volatile并不意味着线程每次都会去主内存中获取最新的值!
volatile只能保证变量在各个线程中的可见性,但不能保证变量操作的原子性。意思就是volatile只能保证每个线程在读取到的变量值是最新的,但是不能保证线程对变量的计算、自增等行为的原子性,即即使线程获取到了最新的值,但是在非原子性操作过程中,变量的值仍有可能被其他线程修改。
volatile的适用场景
通常来说,使用volatile必须具备以下2个条件:
1)对变量的写操作不依赖于当前值
2)该变量没有包含在具有其他变量的不变式中
通俗来说,就是只有保证对变量的操作具有原子性,才能保证使用volatile关键字的程序在并发时能够正确执行。 值得注意的是变量自增i++,不具有原子性
下面列出两个现实开发中常用的使用场景:
1.状态量flag
public class MyThread extends Thread{
private volatile static boolean flag = true;
@Override
public void run() {
while (!flag){
doSomething;
}
}
}
线程中需要对一个状态量进行判断然后doSomething,这个时候一旦其他线程修改了flag状态,另外一个线程立马就能感知到
2.双重校验(单例模式)
public class Singleton {
private volatile static Singleton singleton;
//创建Singleton实例的方法
public Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
这里可能有人不理解为什么在synchronized代码块中还需要判断一次singleton是否为null?,当内存中没有singleton实例时,也就是singleton == null,假如有两个线程1,2同时判断singleton == null为true,那么都会进入if代码块,线程1获取到锁并执行了创建singleton实例的代码,线程1释放锁,线程2获得锁,如果不加singleton == null的判断,那么线程而会在创建一次single同对象,也就不符合单例模式的规则了。
volatile关键字的理解的更多相关文章
- volatile关键字深入理解
前言: 这个关键字的重点就三个字,就是可见性.但是面试的时候,你说出可见性三个字,基本上满分100的话,最多只能得到20分.剩下的那80分,就要靠你用硬功夫去获得了. 所谓的硬功夫,其实就是要整明白, ...
- java中volatile关键字的理解
一.基本概念 Java 内存模型中的可见性.原子性和有序性.可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有 ...
- 谈谈对volatile关键字的理解
1. volatile的特性 volatile是Java语言提供的一种轻量级的同步机制,用来确保将变量得更新操作通知到其它线程.具备三种特性: 保证变量的可见性: 对于volatile修饰的变量进行单 ...
- java volatile关键字的理解
转载:http://shmilyaw-hotmail-com.iteye.com/blog/1672779 一个多线程的示例引发的问题 在讨论这个关键字之前先看一个多线程的示例代码: public c ...
- 对volatile关键字的理解
本文是基于对 http://www.cnblogs.com/aigongsi/archive/2012/04/01/2429166.html 这篇文档的理解 volatile 用volatile修饰的 ...
- java并发编程 volatile关键字 精准理解
1.volatile的作用 一个线程共享变量(类的成员变量.类的静态成员变量等)被volatile修饰之后,就具有以下作用: 1)并发中的变量可见性(不同线程对该变量进行操作时的可见性),即一个线程修 ...
- 面试官最爱的volatile关键字
在Java相关的岗位面试中,很多面试官都喜欢考察面试者对Java并发的了解程度,而以volatile关键字作为一个小的切入点,往往可以一问到底,把Java内存模型(JMM),Java并发编程的一些特性 ...
- Java面试官最常问的volatile关键字
在Java相关的职位面试中,很多Java面试官都喜欢考察应聘者对Java并发的了解程度,以volatile关键字为切入点,往往会问到底,Java内存模型(JMM)和Java并发编程的一些特点都会被牵扯 ...
- 面试必问的volatile关键字
原文: 卡巴拉的树 https://juejin.im/post/5a2b53b7f265da432a7b821c 在Java相关的岗位面试中,很多面试官都喜欢考察面试者对Java并发的了解程度, ...
随机推荐
- iOS 后台任务
首先开启后台任务 使用设置后台任务触发的时机 application.setMinimumBackgroundFetchInterval(UIApplication.backgroundFetchIn ...
- 吴裕雄--天生自然 R语言开发学习:基础知识
1.基础数据结构 1.1 向量 # 创建向量a a <- c(1,2,3) print(a) 1.2 矩阵 #创建矩阵 mymat <- matrix(c(1:10), nrow=2, n ...
- highcharts 设置柱子之间的距离 柱子宽度
plotOption : { column : { // 设置每个柱自身的宽度 pointWidth : // x轴每个点只用一个柱,则这个属性设置的是相邻的两个点的柱之间的间距. // 如果x轴每个 ...
- deeplearning.ai 改善深层神经网络 week2 优化算法
这一周的主题是优化算法. 1. Mini-batch: 上一门课讨论的向量化的目的是去掉for循环加速优化计算,X = [x(1) x(2) x(3) ... x(m)],X的每一个列向量x(i)是 ...
- win10安装revit失败,怎么强力卸载删除注册表并重新安装
一些搞设计的朋友在win10系统下安装revit失败或提示已安装,也有时候想重新安装revit的时候会出现本电脑windows系统已安装revit,你要是不留意直接安装revit,只会安装revit的 ...
- python爬虫心得(第一天)
爬虫是什么? 我个人觉得用简单通俗的话来说就是在浏览网页的过程中将有价值的信息下载到本地硬盘或者是储存到数据库中的行为. 爬虫的基础认知 可以参考此链接:https://www.imooc.com/a ...
- maven工程项目依赖爆红,手动导入依然缺少依赖
1.新建一个工程 2.把依赖添加到新建工程的pom文件 神奇的事情发生了,依赖自动补全!!! 3.点击install 安装一下可能有些依赖会有其他依赖 建议:不要在自己原来的工程上浪费时间,新建工程. ...
- json/xml processing model与xml和json的简要区别
1.JavaScript Object Notation(JSON) JSON是一种轻量级数据交换格式,广泛用作通用格式,用于序列化和反序列化通过Internet相互通信的应用程序中的数据.这些应用程 ...
- liubo.im
elite-lessons (37) --> 1025 精英水平的道歉 29/10/2016 1027 听大脑说话.给大脑编程 27/10/2016 1022 美国两党政治为什么越来越极化? 2 ...
- poi报表导出4.1.0版本工具类 导出并下载
这一段时间,由于项目上线基于稳定,所以我这边在基于我们一期迭代的分支上优化一部分我们之前没有做的功能,报表导出.本身之前用的是3.5的版本,但是由于同事要写导入,写的代码只有4.1.0的版本支持,所以 ...