阅读笔记-violatile关键字如何保证可见性

从Java内存模型出发

在Java内存模型中,每个线程,都有一个工作内存,它们与主内存交换数据。
在这里插入图片描述

现在主内存有一个数据data=0,线程1和线程2都需要用到这个data,就复制到工作内存当中。线程1和线程2的工作内存现在各有一份data数据。
在这里插入图片描述
为什么要这么做,而不是直接从主内存去读取data
平时开发的Java代码,在运行时,都会翻译为机器指令给CPU执行,每次执行时的变量如果都从主内存中去加载,性能就会很差,为什么会很差?因为随着技术的发展,CPU的执行速度越来越快,内存的读取写入速度却发展缓慢,现在CPU的执行速度比内存的读取写入速度要快很多,所以就导致CPU总是等待内存读取写入数据,耗时。

那要怎么解决这个问题?
为了能够解决CPU和内存的性能问题,人们想出来了一个好的办法,就是在 CPU 和内存之间增加高速缓存,可以类比于JMM中的工作内存
缓存的概念大家都知道,就是保存一份数据拷贝。它的特点是速度快,内存小,并且价格昂贵。那么,程序的执行过程就变成了:程序在运行过程中,会将运算需要的数据从主存复制一份到 CPU 的高速缓存当中。
那么 CPU 进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。

简单来说的话,因为为了照顾CPU的性能,减少等待的时间,所以需要先加载数据到工作内存,运算结束在刷新到主内存中。

不过,这样虽然解决了性能上的问题,但是又引发了并发的问题。

Java并发问题

可见性问题

在这里插入图片描述
线程1修改了data=1,线程2和主内存依然只看到data=0(此时data没有立刻刷新会主内存),只有线程1能够读取到最新值,这就是可见性问题。

这就导致,线程1和线程2虽然都是在操作一个变量data,但是线程1修改了data变量的值之后,线程2是看不到的,一直都是看到自己本地工作内存中的一个旧副本的值!

用理论的话来描述可见性问题:

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

volatile 关键字的作用

那么如何解决上面说到的可见性的问题?这时候需要用到volatile关键字了。

1. volatile关键字使修饰变量强制刷回主内存

public class HelloWorld{
	private volatile Integer data = 0;
}

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

在这里插入图片描述

2.violatile关键字修饰会让其他副本失效过期

如果此时别的线程的工作内存中有这个data变量的本地缓存,也就是一个变量副本的话,那么会强制让其他线程的工作内存中的data变量缓存直接失效过期,不允许再次读取和使用了
在这里插入图片描述

总结:
以上就是演示了volatile关键字如何解决JMM的可见性问题。
第一,就是强制修改后的变量副本刷回主内存,这样的话主内存中的值就能够保持最新
第二,让其他线程的变量副本过期,从主内存重新加载最新的值。

题外话

上面仅仅讨论了volatile关键字 能够解决可见性问题。
volatile关键字不仅能够解决可见性问题,还能保证有序性,但是并不能解决Java并发的原子性问题。
如果多个线程同时去修改data,那么最终会导致修改值混乱,volatile关键字是无法解决这样的场景的。

原子性问题需要用到synchronized关键字,ReentrantLock等加锁机制来解决。

参考

https://zhuanlan.zhihu.com/p/91621286
https://mp.weixin.qq.com/s/DmE9yyehx02YRsnlBAB1Fg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值