java中volatile关键字的作用详解
作者:BeanInJ
1、volatile保证可见性
volatile可以保证,若一个线程改变了某块内存的值,其他线程是可见的,以至于其他线程能及时更新这块内存。
线程拥有自己的内存空间: 每个线程在运行时,都有自己的空间去加载缓存中的值,如果一个值发生改变,会先改变在线程中的值,再在一定时间内同步到缓存中。
volatile可见性: 当两个线程使用同一变量M时,线程1改变了M的值,如果不使用volatile,线程2可能感知不到M发生了改变,继续拿着M在缓存中的值运行。使用volatile的变量,在线程1改变M时,对其他线程来说就是可见的,就会去更新M的值。
其他发生内存刷新的情况: 有些java代码是已经包含了刷新内存、内存同步的操作,这会使得一些变量不加volatile,也会在多线程中及时更新。例如:调用System.out.println()会刷新内存
2、volatile保证顺序性
volatile修饰的内存,可以(利用 jvm中的内存屏障)保证它在多个代码行中读写的执行是有顺序的。
2.1、重排序与内存屏障
为什么会重排序? 为了提高CPU效率,在结果一致性的前提下,在执行一些较为耗时的操作,CPU并不会空着等待它执行完毕再继续,而是继续执行下面的代码。
怎么阻止这种不按顺序执行的情况? 如上图,在第二行和第三行之间加一条内存屏障指令,当机器读到内存屏障指令时,就知道要等上一行执行完,才能执行下一行。
内存屏障有cpu级别的和jvm级别的,cpu级别靠汇编语言特有的指令实现
2.2、jvm中的内存屏障
jvm规范规定,jvm必须实现的4中屏障:LL、LS、SL、SS
L (Load) ,指的是从内存中读一个数据到CPU S (Store),指的是从CPU中写一个数据到内存
LL指第一行是从内存中读一个数据到CPU,第二行也是从内存中读一个数据到CPU,中间加的内存屏障类型就叫LoadLoadBarrier
LS指第一行是从内存中读一个数据到CPU,第二行从CPU中写一个数据到内存,中间加的内存屏障类型就叫LoadStoreBarrier
到此这篇关于java中volatile关键字的作用详解的文章就介绍到这了,更多相关volatile关键字的作用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!