大白话聊聊Java并发面试问题之volatile究竟是什么?【石杉的架构笔记】

欢迎关注微信公众号:石杉的架构笔记(id:shishan100)java

个人新课**《C2C 电商系统微服务架构120天实战训练营》在公众号儒猿技术窝**上线了,感兴趣的同窗,能够点击下方连接了解详情:面试

《C2C 电商系统微服务架构120天实战训练营》算法

1、写在前面

前段时间把几年前带过的一个项目架构演进的过程整理了一个系列出来,参见(亿级流量架构系列专栏总结)。编程

不过不少同窗看了以后,后台反馈说文章太烧脑,看的云里雾里。其实这个也正常,文章承载的信息毕竟有限,而架构的东西细节太多,想要仅仅经过文章看懂一个系统架构的设计和落地,确实难度不小。缓存

因此接下来用大白话跟你们聊点轻松的话题,比较易于理解,并且对你们工做和面试都颇有帮助。安全

2、场景引入,问题初现

不少同窗出去面试,都会被问到一个常见的问题:说说你对volatile的理解?性能优化

很多初出茅庐的同窗可能会有点措手不及,由于可能就是以前没关注过这个。可是网上百度一下呢,很多文章写的很好,可是理论扎的太深,文字太多,图太少,让人有点难以理解。微信

基于上述痛点,这篇文章尝试站在年轻同窗的角度,用最简单的大白话,加上多张图给你们说一下,volatile究竟是什么?markdown

固然本文不会把理论扎的太深,由于一会儿扎深了文字太多,不少同窗仍是会很差理解。多线程

本文仅仅是定位在用大白话的语言将volatile这个东西解释清楚,而涉及到特别底层的一些原理和技术问题,之后有机会开文再写。

首先,给你们上一张图,我们来一块儿看看:

如上图,这张图说的是java内存模型中,每一个线程有本身的工做内存,同时还有一个共享的主内存。

举个例子,好比说有两个线程,他们的代码里都须要读取data这个变量的值,那么他们都会从主内存里加载data变量的值到本身的工做内存,而后才可使用那个值。

好了,如今你们从图里看到,每一个线程都把data这个变量的副本加载到了本身的工做内存里了,因此每一个线程均可以读到data = 0这个值。

这样,在线程代码运行的过程当中,对data的值均可以直接从工做内存里加载了,不须要再从主内存里加载了。

那问题来了,为啥必定要让每一个线程用一个工做内存来存放变量的副本以供读取呢?我直接让线程每次都从主内存加载变量的值不行吗?

很简单!由于线程运行的代码对应的是一些指令,是由CPU执行的!可是CPU每次执行指令运算的时候,也就是执行咱们写的那一大坨代码的时候,要是每次须要一个变量的值,都从主内存加载,性能会比较差!

因此说后来想了一个办法,就是线程有工做内存的概念,相似于一个高速的本地缓存。

这样一来,线程的代码在执行过程当中,就能够直接从本身本地缓存里加载变量副本,不须要从主内存加载变量值,性能能够提高不少!

可是你们思考一下,这样会有什么问题?

咱们来设想一下,假如说线程1修改了data变量的值为1,而后将这个修改写入本身的本地工做内存。那么此时,线程1的工做内存里的data值为1。

然而,主内存里的data值仍是为0!线程2的工做内存里的data值仍是0啊?!

这可尴尬了,那接下来,在线程1的代码运行过程当中,他能够直接读到data最新的值是1,可是线程2的代码运行过程当中读到的data的值仍是0!

这就致使,线程1和线程2其实都是在操做一个变量data,可是线程1修改了data变量的值以后,线程2是看不到的,一直都是看到本身本地工做内存中的一个旧的副本的值!

这就是所谓的java并发编程中的可见性问题

多个线程并发读写一个共享变量的时候,有可能某个线程修改了变量的值,可是其余线程看不到!也就是对其余线程不可见!

3、volatile的做用及背后的原理

那若是要解决这个问题怎么办呢?这时就轮到volatile闪亮登场了!你只要给data这个变量在定义的时候加一个volatile,就直接能够完美的解决这个可见性的问题。

好比下面的这样的代码,在加了volatile以后,会有啥做用呢?

完整的做用就不给你们解释了,由于咱们定位就是大白话,要是把底层涉及的各类内存屏障、指令重排等概念在这里带出来,很多同窗又要蒙圈了!

咱们这里,就说说他最关键的几个做用是啥?

第一,一旦data变量定义的时候前面加了volatile来修饰的话,那么线程1只要修改data变量的值,就会在修改完本身本地工做内存的data变量值以后,强制将这个data变量最新的值刷回主内存,必须让主内存里的data变量值立马变成最新的值!

整个过程,以下图所示:

第二,若是此时别的线程的工做内存中有这个data变量的本地缓存,也就是一个变量副本的话,那么会强制让其余线程的工做内存中的data变量缓存直接失效过时,不容许再次读取和使用了!

整个过程,以下图所示:

第三,若是线程2在代码运行过程当中再次须要读取data变量的值,此时尝试从本地工做内存中读取,就会发现这个data = 0已通过期了!

此时,他就必须从新从主内存中加载data变量最新的值!那么不就能够读取到data = 1这个最新的值了!整个过程,参见下图:

bingo!好了,volatile完美解决了java并发中可见性的问题!

对一个变量加了volatile关键字修饰以后,只要一个线程修改了这个变量的值,立马强制刷回主内存。

接着强制过时其余线程的本地工做内存中的缓存,最后其余线程读取变量值的时候,强制从新从主内存来加载最新的值!

这样就保证,任何一个线程修改了变量值,其余线程立马就能够看见了!这就是所谓的volatile保证了可见性的工做原理!

4、总结 & 提醒

最后给你们提一嘴,volatile主要做用是保证可见性以及有序性。

有序性涉及到较为复杂的指令重排、内存屏障等概念,本文没说起,可是volatile是不能保证原子性的

也就是说,volatile主要解决的是一个线程修改变量值以后,其余线程立马能够读到最新的值,是解决这个问题的,也就是可见性!

可是若是是多个线程同时修改一个变量的值,那仍是可能出现多线程并发的安全问题,致使数据值修改错乱,volatile是不负责解决这个问题的,也就是不负责解决原子性问题!

原子性问题,得依赖synchronized、ReentrantLock等加锁机制来解决

END

若有收获,请帮忙转发,您的鼓励是做者最大的动力,谢谢!

一大波微服务、分布式、高并发、高可用的原创系列文章正在路上

欢迎扫描下方二维码,持续关注:

石杉的架构笔记(id:shishan100)

十余年BAT架构经验倾囊相授

**> **推荐阅读:** > > 一、[拜托!面试请不要再问我Spring Cloud底层原理](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Flink.juejin.im%25252525252F%25252525253Ftarget%25252525253Dhttps%2525252525253A%2525252525252F%2525252525252Flink.juejin.im%2525252525252F%2525252525253Ftarget%2525252525253Dhttps%252525252525253A%252525252525252F%252525252525252Fjuejin.im%252525252525252Fpost%252525252525252F5be13b83f265da6116393fc7) > > 二、[【双11狂欢的背后】微服务注册中心如何承载大型系统的千万级访问?](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Flink.juejin.im%25252525252F%25252525253Ftarget%25252525253Dhttps%2525252525253A%2525252525252F%2525252525252Flink.juejin.im%2525252525252F%2525252525253Ftarget%2525252525253Dhttps%252525252525253A%252525252525252F%252525252525252Fjuejin.im%252525252525252Fpost%252525252525252F5be3f8dcf265da613a5382ca) > > 三、[【性能优化之道】每秒上万并发下的Spring Cloud参数优化实战](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Flink.juejin.im%25252525252F%25252525253Ftarget%25252525253Dhttps%2525252525253A%2525252525252F%2525252525252Flink.juejin.im%2525252525252F%2525252525253Ftarget%2525252525253Dhttps%252525252525253A%252525252525252F%252525252525252Fjuejin.im%252525252525252Fpost%252525252525252F5be83e166fb9a049a7115580) > > 四、[微服务架构如何保障双11狂欢下的99.99%高可用](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Flink.juejin.im%25252525252F%25252525253Ftarget%25252525253Dhttps%2525252525253A%2525252525252F%2525252525252Flink.juejin.im%2525252525252F%2525252525253Ftarget%2525252525253Dhttps%252525252525253A%252525252525252F%252525252525252Fjuejin.im%252525252525252Fpost%252525252525252F5be99a68e51d4511a8090440) > > 五、[兄弟,用大白话告诉你小白都能听懂的Hadoop架构原理](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Flink.juejin.im%25252525252F%25252525253Ftarget%25252525253Dhttps%2525252525253A%2525252525252F%2525252525252Flink.juejin.im%2525252525252F%2525252525253Ftarget%2525252525253Dhttps%252525252525253A%252525252525252F%252525252525252Fjuejin.im%252525252525252Fpost%252525252525252F5beaf02ce51d457e90196069) > > 六、[大规模集群下Hadoop NameNode如何承载每秒上千次的高并发访问](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Flink.juejin.im%25252525252F%25252525253Ftarget%25252525253Dhttps%2525252525253A%2525252525252F%2525252525252Flink.juejin.im%2525252525252F%2525252525253Ftarget%2525252525253Dhttps%252525252525253A%252525252525252F%252525252525252Fjuejin.im%252525252525252Fpost%252525252525252F5bec278c5188253e64332c76) > > 七、【[性能优化的秘密】Hadoop如何将TB级大文件的上传性能优化上百倍](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Flink.juejin.im%25252525252F%25252525253Ftarget%25252525253Dhttps%2525252525253A%2525252525252F%2525252525252Flink.juejin.im%2525252525252F%2525252525253Ftarget%2525252525253Dhttps%252525252525253A%252525252525252F%252525252525252Fjuejin.im%252525252525252Fpost%252525252525252F5bed82a9e51d450f9461cfc7) > > 八、[拜托,面试请不要再问我TCC分布式事务的实现原理](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Flink.juejin.im%25252525252F%25252525253Ftarget%25252525253Dhttps%2525252525253A%2525252525252F%2525252525252Fjuejin.im%2525252525252Fpost%2525252525252F5bf201f7f265da610f63528a)[坑爹呀!](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Fjuejin.im%25252525252Fpost%25252525252F5bf2c6b6e51d456693549af4) > > 九、[【坑爹呀!】最终一致性分布式事务如何保障实际生产中99.99%高可用?](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Fjuejin.im%25252525252Fpost%25252525252F5bf2c6b6e51d456693549af4) > > 十、[拜托,面试请不要再问我Redis分布式锁的实现原理!](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Fjuejin.im%25252525252Fpost%25252525252F5bf3f15851882526a643e207) > > **十一、****[【眼前一亮!】看Hadoop底层算法如何优雅的将大规模集群性能提高10倍以上?](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Flink.juejin.im%252525253Ftarget%252525253Dhttps%25252525253A%25252525252F%25252525252Fjuejin.im%25252525252Fpost%25252525252F5bf5396f51882509a768067e)** > > **十二、****[亿级流量系统架构之如何支撑百亿级数据的存储与计算](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Flink.juejin.im%2525252F%2525253Ftarget%2525253Dhttps%252525253A%252525252F%252525252Fjuejin.im%252525252Fpost%252525252F5bfab59fe51d4551584c7bcf)** > > 1三、[亿级流量系统架构之如何设计高容错分布式计算系统](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Flink.juejin.im%25253Ftarget%25253Dhttps%2525253A%2525252F%2525252Fjuejin.im%2525252Fpost%2525252F5bfbeeb9f265da61407e9679) > > 1四、[亿级流量系统架构之如何设计承载百亿流量的高性能架构](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Flink.juejin.im%253Ftarget%253Dhttps%25253A%25252F%25252Fjuejin.im%25252Fpost%25252F5bfd2df1e51d4574b133dd3a) > > 1五、[亿级流量系统架构之如何设计每秒十万查询的高并发架构](https://link.juejin.im?target=https%3A%2F%2Flink.juejin.im%2F%3Ftarget%3Dhttps%253A%252F%252Fjuejin.im%252Fpost%252F5bfe771251882509a7681b3a) > > 1六、[亿级流量系统架构之如何设计全链路99.99%高可用架构](https://link.juejin.im?target=https%3A%2F%2Fjuejin.im%2Fpost%2F5bffab686fb9a04a102f0022) > > 1七、[七张图完全讲清楚ZooKeeper分布式锁的实现原理](https://juejin.cn/post/6844903729406148622)**
相关文章
相关标签/搜索