【volatile原理】volatile原理


一、什么是volatile

volatile是Java提供的一种轻量级的同步机制。Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量,相比synchronized的加锁方式来解决共享变量的内存可见性问题,volatile就是更轻量的选择,他没有上下文切换的额外开销成本。使用volatile声明的变量,可以确保值被更新的时候对其他线程立刻可见,简单来说就是,会导致其他CPU中对应的缓存值无效。volatile使用内存屏障来保证不会发生指令重排,解决了内存可见性的问题。但是volatile 变量的同步性较差(有时它更简单并且开销更低),而且其使用也更容易出错。

二、volatile原理

线程都是从主内存中读取共享变量到工作内存来操作,完成之后再把结果写会主内存,但是这样就会带来可见性问题。举个例子,假设现在我们是两级缓存的双核CPU架构,包含L1、L2两级缓存。
(1)线程1首先获取变量X的值,由于最初两级缓存都是空,所以直接从主内存中读取X,假设X初始值为0,线程1读取之后把X值都修改为1,同时写回主内存。这时候缓存和主内存的情况如下图。
在这里插入图片描述
(2)线程2也同样读取变量X的值,由于L2缓存已经有缓存X=1,所以直接从L2缓存读取,之后线程2把X修改为2,同时写回L2和主内存。这时候的X值入下图所示。
在这里插入图片描述

这时候线程1如果再想获取变量X的值,因为L1缓存已经有x=1了,所以这时候变量内存不可见问题就产生了,线程2将X修改为2对线程1来说没有感知,就是线程1不知道这时候X的值已经变成2了。
但是,如果X变量用volatile修饰的话,当线程1再次读取变量X的话,CPU就会根据缓存一致性协议强制线程1重新从主内存加载最新的值到自己的工作内存,而不是直接用缓存中的值。

在JVM底层volatile是采用内存屏障来实现的。内存屏障会提供3个功能:
(1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;简单来说就是,执行到volatile变量时,其前面的所有语句都执行完后面所有语句都未执行。且前面语句的结果对volatile变量及其后面语句可见。
(2)它会强制将对缓存的修改操作立即写入主存
(3)如果是写操作,它会导致其他CPU中对应的缓存行无效。确保值被更新的时候对其他线程立刻可见


此篇文章为学习笔记,是对别人知识的理解,加上自己的一些个人理解汇聚而成。若有侵权联系删除。写作不易,望好兄弟们来个三连支持。感激不尽
注:原文出处为https://mp.weixin.qq.com/s/-xFSHf7Gz3FUcafTJUIGWQ

猜你喜欢

转载自blog.csdn.net/qq_51720181/article/details/125630293