volatile关键字的使用心得

在读一篇文章的时候,作者对volatile的使用场景就生动解释了它的使用误区:

不要在依靠volatile变量现有值的情况下对其自身做修改

其实就是不要拿volatile变量做多步骤的操作就是了。

volatile变量单纯的读或写操作是可以的,例如:

volatile int count = 1;

单纯的写操作,直接将value赋值给count,不用读取count变量。

这种操作相等于带锁的原子操作,因为其本身就是不可再分割的最小操作了。

public void inc(int value) {

count = value;

}

直接读取count变量返回。

public int get() {

return count;

}

像 count++ 这种是复合操作。先读取count,再计算,再写回主存。

这篇文章的情景类似:

Java Concurrency: AtomicReference - DZone Java

volatile不是保证变量最新值么,我一开始不理解,就是count被读入a cpu的cache中,在另外一个b cpu修改了值且写回主存后,由于缓存一致性协议的作用,会使a中的cache的count无效,a再做计算时应该重新读主存。

我思索良久,查了些资料。我想能解释这种现象只能是这样了:

我们知道 cpu 执行代码都是执行代码被编译之后的指令。

cpu都是顺序执行,a先把count读到cache,b紧接着计算了count写回了主存,并且使其他cpu中的cache的count无效。但是同时 a 也在向下执行,执行到calculate指令,计算完毕后再写回主存。就发生了覆盖问题。

通过这种推理可以发现,如果a在 load 指令的时候发现 count 无效了,会从主存再次 read,但是a已经过了load指令,就不会再次检查变量的有效性问题了。

所以volatile变量只保证每次读取变量时的可见性,所以在使用变量的过程中,有可能此时变量就已经被其他线程修改了!!!

read 从内存中读值存入CPU的高速缓存

load 将数据加载进CPU计算

store CPU将值存到高速缓存

write 将数据从高速缓存写回内存 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值