关于volatile关键字的作用和原理

导读:本篇文章讲解 关于volatile关键字的作用和原理,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

在很多面试中会经常被问到“volatile”关键字,而volatile关键字是java并发编程中一个非常重要的关键字,这个问题也是比较底层的,下面让我来分享一下我关于这两个问题的一些理解~希望可以帮助到大家~

首先,我们先简单了解一下什么是volatile?volatile 是 Java 中的关键字,是一个变量修饰符,被用来修饰会被不同线程访问和修改的变量,是java虚拟机提供的轻量级的同步机制。

一、volatile关键字的作用

volatile 关键字有两个作用

  • 可以保证在多线程环境下共享变量的可见性
  • 可以屏蔽在多线程环境下CPU的指令重排

可见性:当某一个线程对共享变量的修改,其他线程可以立刻看到修改之后的值

这个可见性的问题,我认为本质上是由以下两个方面造成的:

首先是CPU的高速缓存,如下图所示在CPU里面设计了三级缓存,它用来去解耦CPU的运算效率和内存IO的效率问题,但是这样的设计,又带来了缓存的一致性问题,而在多线程并行的情况下,缓存一致性又会导致可见性的问题,所以,对于加了volatile关键字修饰的共享变量来说,JVM虚拟机会自动增加一个Lock的一个汇编指令,那么这个指令会根据CPU的型号自动添加给总线锁或者是缓存锁

关于volatile关键字的作用和原理

下面简单介绍一下上述两种锁:

总线锁是锁定了CPU的前端总线,从而导致在同一时刻,只有一个线程去内存通讯,这样,就避免了多线程并发造成的可见性,缓存锁则是对总线锁的优化,因为总线锁的使用,导致了CPU的使用效率大幅下降,所以缓存锁只针对于CPU的三级缓存中的目标数据进行加锁,而缓存锁是使用MESI缓存一致性来实现的。

屏蔽指令重排:屏蔽CPU指令重排序。在多线程环境下,CPU指令的编写顺序和执行顺序不一致,从而导致可见性问题

为了提升 CPU 的利用率,CPU引入了StoreBuffer机制,而这一种优化机制会导致 CPU 的乱序执行

为了避免这样的问题,CPU 提供了内存屏障指令,上层应用可以在合适的地方插入内存屏障来避免CPU 指令重排序问题。而volatile就是通过设置内存屏障,来禁止指令重排的。

二、volatile的实现原理分析

1、volatile会在变量写操作前后加入内存屏障

关于volatile关键字的作用和原理

 如上图所示,volatile会在变量写操作前后加入两个内存屏障,来保证前面写的指令和后面读的指令是有序的

2、volatile在变量的读操作后插入两个指令

关于volatile关键字的作用和原理

如上图所示,volatile在变量的读操作后插入两个指令,禁止后面的读指令和写指令重排序。volatile可以看作是轻量级的synchronized,虽然说volatile不能保证原子性,但是如果在多线程环境下的操作本身就是原子操作的话,那么使用volatile会优于synchronized。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/81347.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!