java面试总躲不过的并发(二):volatile原理 + happens-before原则
一.happens-before原则
同一个线程中的,前面的操作 happens-before 后续的操作。(即单线程内按代码顺序执行。但是,在不影响在单线程环境执行结果的前提下,编译器和处理器可以进行重排序,这是合法的。换句话说,这一是规则无法保证编译重排和指令重排)。
1. 监视器上的解锁操作 happens-before 其后续的加锁操作。(Synchronized 规则)
2. 对volatile变量的写操作 happens-before 后续的读操作。(volatile 规则)
3. 线程的start() 方法 happens-before 该线程所有的后续操作。(线程启动规则)
4. 线程所有的操作 happens-before 其他线程在该线程上调用 join 返回成功后的操作。
5. 如果 a happens-before b,b happens-before c,则a happens-before c(传递性)
二.volatile关键字的作用
Volatile关键字主要用于保证内存可见性和顺序性:
1.volatile修饰的变量可以保证一个线程对该变量的写happens-before 一个线程对该变量的读
2.Volatile可以用来修饰long和double类型的变量使其以原子方式执行
3.Volatile在双重检查加锁的单例模式中的应用,可以防止重排序
三.volatile关键字的实现原理
在java代码编译成字节码时会在volatile修饰的共享变量进行写操作的时候会多出Lock前缀的指令。
我们知道为了提高处理速度,CPU不直接和内存进行通信,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作,但操作完不知道何时会写回内存。如果对声明了volatile的变量进行写操作,JVM就会向CPU发送一条Lock前缀的指令,将这个变量所在缓存行的数据写回到系统内存。但是,就算写回到内存,如果其他处理器缓存的值还是旧的,再执行计算操作就会有问题。所以,在多处理器下,为了保证各个CPU的缓存是一致的,就会实现缓存一致性协议,每个CPU通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前CPU的缓存行设置成无效状态,当CPU对这个数据进行修改操作的时候,会重新从系统内存中把数据读到处理器缓存里
- Lock前缀的指令会引起CPU缓存写回内存;
- 一个CPU的缓存回写到内存会导致其他处理器的缓存失效;
- 当CPU发现本地缓存失效后,就会从内存中重读该变量数据,即可以获取当前最新值。
这样针对volatile变量通过这样的机制就使得每个线程都能获得该变量的最新值
volatile相关的理解就写到这里,如果大家还想详细的了解volatile可以查阅相关资料或者私信我进行交流。
并发是java中无法避免的问题,基本上java面试都会涉及一些并发相关的问题,尤其是互联网公司一定会问到,今天就先写到了这里,下次准备把并发中相关的锁和并发集合的知识整理一下分享给大家,如果喜欢记得关注我【不爱八阿哥】,有什么问题也可以私信交流,让我们共同进步。
来源:https://www.toutiao.com/i6656572928701760004/
java面试总躲不过的并发(二):volatile原理 + happens-before原则的更多相关文章
- java面试总躲不过的并发(一): 线程池ThreadPoolExecutor基础梳理
本文核心:线程池ThreadPoolExecutor基础梳理 一.实现多线程的方式 1.继承Thread类,重写其run方法 2.实现Runnable接口,实现run方法 3.实现Callable接口 ...
- Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理
相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池Thr ...
- Java面试知识点之线程篇(二)
前言:接上篇,这里继续对java线程相关知识点进行总结. 1.notify和notifyall的区别 notify()方法能够唤醒一个正在等待该对象的monitor的线程,当有多个线程都在等待该对象的 ...
- Java面试不得不知的程序(二)
[程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 斐波那契数列:前面相邻两项之和,构 ...
- 死磕Java面试系列:深拷贝与浅拷贝的实现原理
深拷贝与浅拷贝的问题,也是面试中的常客.虽然大家都知道两者表现形式不同点在哪里,但是很少去深究其底层原理,也不知道怎么才能优雅的实现一个深拷贝.其实工作中也常常需要实现深拷贝,今天一灯就带大家一块深入 ...
- 【Java面试】Zookeeper中的Watch机制的原理?
一个工作了7年的粉丝,遇到了一个Zookeeper的问题. 因为接触过Zookeeper这个技术,不知道该怎么回答. 我说一个工作了7年的程序员,没有接触过主流技术,这不正常. 于是我问了他工资以后, ...
- 【Java面试】请说一下ReentrantLock的实现原理?
一个工作了3年的粉丝私信我,在面试的时候遇到了这样一个问题. "请说一下ReentrantLock的实现原理",他当时根据自己的理解零零散散的说了一些. 但是似乎没有说到关键点上, ...
- Java面试知识点之线程篇(一)
前言:在Java面试中,一定会遇到线程相关问题,因此笔者在这里总结Java中有关线程方面知识点,多数从网上得来(文中会贴出主要参考链接),有些也是笔者在面试中所遇到的问题,如有错误,请不吝指正.主要参 ...
- Java线程池使用和分析(二) - execute()原理
相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的 ...
随机推荐
- Tasklist使用详解
用jstat查看jvm内存的使用的情况时,因为是windows机器,不能使用top命令方便的查出来,进程好在网上搜了一下看到了在windows原来使用的是tasklist 特意将tasklist的用法 ...
- Elasticsearch安装部署教程
1)下载elasticsearch-1.1.2.zip 2)用ssh工具连接目录主机,在命令窗口输入:mkdir -p /opt/elasticsearch创建elasticsearch文件夹 3 ...
- servlet操作本地文件汇总: 判断文件是否存在;文件重命名;文件复制; 获取文件属性信息,转成Json对象; 获取指定类型的文件; 查找替换.txt中的文本
package servlet; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; ...
- H5页面访问java后台进行登录拦截
1.未登录状态下进行拦截,回到登录页面 function judgeLogin(currentPage) { var judge=false; var storage=window.localStor ...
- /usr/lib/x86_64-linux-gnu/libopencv_highgui.so:对‘TIFFReadRGBAStrip@LIBTIFF_4.0’未定义的引用
LIBRARIES += boost_thread stdc++ boost_regex https://github.com/rbgirshick/fast-rcnn/issues/52
- win10安装pytorch
安装gpu版本的pytorch需要三个东西:pytorch(torchvision).cuda.cudnn 相信大家都安装过了anaconda,就不介绍anaconda的安装了 1.安装cuda:从官 ...
- Python第七章(北理国家精品课 嵩天等)
7.1文件的使用 1.1文本类型 文本文件:由单一特定编码组成的文件,如.txt 二进制文件:如.png,.avi 1.2文件的打开和关闭 打开-操作-关闭 <变量名> = open(&l ...
- vue中使用ajax
var vue = new Vue({ el:"#vueid", data:{ selectById : "", }, methods:{ yourMethod ...
- hive防止数据被误删除
1.HDFS层面开启trash功能(fs.trash.interval) 被删除的数据在HDFS中的/user/$USER/.Trash目录中,开启这个功能秩序要将配置属性fs.trash.inter ...
- .NET 并行计算和并发10-lock锁
class Program { private static List<int> intlist; static void Main(string[] args) { intlist = ...