Volatail学习笔记
前言
在面试时,只要问多线程相关的问题,一定绕不开volatile,通过这篇文章我们首先要知道,什么时候会用到volatail,以及他的作用,他的作用背景
一、什么时候会用volatail
volatail是在多线程进行某一数据共享时需要使用的,它可以确保线程之间看到的同一共享数据相同,使得多线程在协作时不会出现操作覆盖。
某一线程对数据进行修改后,其他线程能够快速的得知修改的结果。
想做到快速通知并确保数据的准确,所以使用到了volatail对数据jmm模型进行优化。
二、作用框架JMM
1.JMM内存模型
1.线程,每个线程之间互相隔离。
2.本地内存,每个线程私有,本地内存间也是隔离的。
3.主内存,主内存用来记录每个本地内存中的共享内存。
当线程a执行对共享变量i的赋值操作时,会先进行本地的赋值写入本地内存内。
再由jmm控制加载进主内存中。
此时线程b在读取变量i的时候就会先从本地内存中获取,如果本地缓存中没有,就会请求从主内存中read,读取到本地内存中。在从本地内存中获取变量i的值。
2.物理映射
``Java内存模型与硬件内存架构之间存在差异。硬件内存架构没有区分线程栈和堆。对于硬件,所有的线程栈和堆都分布在主内存中。部分线程栈和堆可能有时候会出现在CPU缓存中和CPU内部的寄存器中。
三、Volatail发挥的作用
1. 保证线程间的本地内存中的共享变量可见
1.1 增加LOCK锁前缀,JVM会发送一个Lock前缀指令给CPU,CPU在执行完写操作后,会立即将新值刷新到主内存
1.2 依赖MESI协议对其他线程中的本地内存中的该变量打上一个过期标识,如果其他线程使用的时候会识别过期标识,直接从主内存中获取当前线程刚写入的数据
2.防止指令重排
2.1 在执行中,在写操作前插入storestore,在写操作之后插入storeload
storestore保证volatile写与之前的写操作指令不会重排序。
storeload保证写完数据之后立即执行flush处理器缓存操作将所有写操作刷到内存,对所有处理器可见。
2.2 在读操作之前插入loadload,在读操作后插入loadstore。
loadload保证在该变量读操作时,如果其他处理修改过,必须从其他处理器高速缓存(或者主内存)加载到自己本地高速缓存。
loadstore保证在读取变量后,禁止volatile读操作与后面任意读写操作重排序。
# 总结
OKOK点到位置,还有就是volatail不能保证原子性,如果执行的操作不是原子操作,还是会有操作覆盖问题。