volatile关键字解析

volatile关键字解析

由于volatile关键字是与Java的内存模型有关的,因此在讲述volatile关键之前,我们先来了解一下与内存模型相关的概念和知识,然后分析了volatile关键字的实现原理.

内存模型相关概念

在计算机执行程序时,每一条指令都是在CPU中执行的,而执行指令的过程中就会牵扯到数据的读取和写入.但是在程序运行的时候临时数据是储存在物理内存中的,那么就会面临一个问题,由于CPU的运行速度很快,但是在内存中读取和存储数据相比于CPU执行指令来说那会慢很多的,那么我们就来想一想如何能改善一下这个现状.
分析:
1.造成原因是因为:数据读取,储存赶不上CPU处理指令的速度.
2.假使俩个人差距太大,如何才能缩小差距,最好的办法有一个中间人,对差的人有帮助提升,对优秀的人积极向其靠拢.
3.那么高速缓存就及时出现了

高速缓存

程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。

例子

i = i + 1;

当线程执行这个语句时,会先从主存当中读取i的值,然后复制一份到高速缓存当中,然后CPU执行指令对i进行加1操作,然后将数据写入高速缓存,最后将高速缓存中i最新的值刷新到主存当中。
 在单线程中,这个模式是没有一点问题的,但是在多线程中,就会出现一些问题,我们都知道在多核CPU中,每一条线程都位于不同的CPU中,那么,就会有资源抢占的问题.如下图解:
 在这里插入图片描述
站长说:“我们现在有100张票,你们谁先买完我就提拔谁当站长”
那么作为有晋升理想的售票员,那肯定会把这一部分票卖的愈多愈好,但是面对顾客的时候就会出现问题.就比如说我有多个顾客在不同的窗口购买票据,但是因为售票员理解错误以为各自都有100张票的权限,可想而知,最终顾客会买到 同一张票的可能性会很大.为什么?(注意我之前提到过多个顾客)
那么遇到这种资源抢占的问题时,我们有以下俩种方式进行解决

  1. 通过在总线加LOCK锁的方式
  2. 通过缓存一致性协议

这俩中方式都是硬件层面上提供的方式.
在以前CPU中,我们习惯在总线程上面添加Lock锁来解决缓存不一致的问题,但是对总线程加锁的话势必会阻塞其他CPU对其他指令的访问从而造成CPU只能为当前的指令服务.那就好比说,上述实例,我只有一个售票窗口,那么我就不会出现购票冲突了.但是这样造成的效率问题同样也很大.
相应的就出现了缓存一致性 最出名的就是Intel 的MESI协议,这个协议说白了就是当CPU写数据时发现当前操作的变量是共享变量,即在其他CPU中也存在该变量的副本,会发出信号通知其他CPU将该变量的缓存行置为无效状态,因此当其他CPU需要读取这个变量时,发现自己缓存中缓存该变量的缓存行是无效的,那么它就会从内存重新读取。

并发编程中的三个概念

在并发编程中我们经常会遇到以下三个问题:

  • 原子性问题
  • 可见性问题
  • 有序性问题

1. 原子性
解释
原子性:就是一个操作或多个操作 要么全部执行并且执行的过程中不会其他行为打断
很经典一个例子就是 银行取钱这个示例,试想一下这些操作都没有原子性,比如A要转钱100给B,结果中途停了,那么由于向B转钱的这个事件已近发生但是A账户并没有进行转钱这一行为(导致A账户还有钱),所以A在取20也是可以的.那么大家想一想,这20元的损失由谁来承担.
所以事务必须具有原子性
2.可见性
可见性,就是指的是多个线程访问同一个变量的时候,一个线程改变了变量的值,其他线程能够立即看到修改的值.

解释

	//CPU执行线程的代码片段1
	int i = 0;
	i = i + 1;

	//CPU执行线程的代码片段2
	w = i;

假使现在这种状态下代码片段1是由CPU1执行的,代码片段2是由CPU2执行,那么当CPU执行代码片段1部分时,我们会将i = 0 + 1的值赋值给高速缓存,但是当CPU赋值给高速缓存中,此时还没写到内存中.那么CPU在执行w = i时候,由于高速缓存没有将数据写入内存中,所以数据还为0.
这就是可见性问题,代码片段1对变量修改之后,代码片段2没有立刻看到代码片段1修改的值.
3.有序性
有序性:即程序执行的顺序按照代码的先后顺序执行
要想并发程序正确地执行,必须要保证原子性、可见性以及有序性。只要有一个没有被保证,就有可能会导致程序运行不正确。

解析volatile关键字

1. volatile关键字的两层语义

  • 保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。
  • 禁止进行指令重排序。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敏姐儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值