Volatile相关知识点和JMM内存模型
谈谈对Volatile的理解
Volatile在单线程开发的用不到的,Volatile是Java虚拟机提供的轻量级的同步机制
Volatile的三大特性
- 保证可见性
- 不保证原子性
- 禁止指令重排
JMM是什么
JMM是java内存模型,英文全称为Java Memory Model,简称JMM,JMM本身是不存在的,是为了我们方便理解抽象化的一种概念,代表的是一组规则和规范,它定义了程序中各个变量的的访问方式
JMM关于同步规定
- 线程在解锁前,必须把共享变量的值刷新到主内存中
- 线程解锁前,必须读取主内存的最新值到线程的自己的工作内存中
- 加锁和解锁是同一把锁
JVM运行的基本单位是线程,每个线程创建是JVM都会为其创建一个工作内存,这个工作内存是线程私有的,java内存模型规定所有的变量都存在主内存中,主内存是共享内存区域,所有的线程都可以访问,但是线程对于共享变量的操作必须复制到自己线程内存中才能进行变量的操作,然后刷新到主内存中,线程之间的通信必须通过主内存来完成
这里解释两个概念,主内存和工作内存
主内存:主内存是计算机内存,就是我们常说的自己常说的4g内存,电脑卡了,加一个8g的内存条
工作内存:
缓存一致性
什么是缓存一致性,当线程A修改了变量A之后刷新到主内存中,其他线程能够马上知晓变量A被修改,其他线程为什么能够被马上知晓?这里用到了总线嗅探技术,总线嗅探技术,为了保证缓存的一致性,这里需要各个处理器访问缓存的时候遵循一些协议,在进行缓存读写的时候按照协议进行相关操作,这类协议主要有MSI,MESI等等
MESI:
当CPU写数据的时候,如果发现操作的变量时共享变量,既在其他CPU中也存在这个变量的副本,会发出信号通知其他CPU将该内存变量的缓存行(缓存行后面在做解释)设置为无效,当这个处理器对这个变量进行修改操作的时候,会重新从主内存中把数据读取到处理器缓存中
总线风暴
总线嗅探技术有一些缺点:
由于Volatile的EMSI缓存一致性协议,需要不断的从主内存嗅探和CAS循环,无效的交互会导致总线带宽达到峰值,因此在自己项目中不要大量使用volatile关键字
JMM的特性
- 可见性
- 原子性
- 有序性
可见性代码验证
结果说明
我们在2处新开了一个线程修改了变量number的值为60,在3处判断判断number==0,为零的话主线程一直等待,我们运行发现1出一直没结束,也没输出线程结束这个输出,这说明没有用volatile修饰的变量,是没有可见行的
当我们在mydata1类成员变量number上加上volatile关键字修饰的时候,我们再来观察