volatail的有序性和可见性

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不能保证原子性,如果执行的操作不是原子操作,还是会有操作覆盖问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值