前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >再也不怕问我volatile关键字,你随便问!!!

再也不怕问我volatile关键字,你随便问!!!

作者头像
Java帮帮
发布2020-07-29 10:29:38
4080
发布2020-07-29 10:29:38
举报

面试官问题:1.Java并发这块了解的怎么样?说说你对volatile关键字的理解?

回答:

volatile是JVM提供的轻量级的同步机制

1.保证可见性

2.保证有序性,禁止指令重排

3.不保证原子性(需要借助synchronized或者CAS)


面试官问题:2.能不能详细说下什么是内存可见性?

回答:

一问到内存的可见性,volatile相关的,直接就把JMM内存模型搬出来好吧。先放图,然后再表演。

以下是俺个人的回答,有不足或漏洞,欢迎大家更正指出!

所谓可见性,是指当一条线程修改了共享变量的值,新值对于其他线程来说是可以立即得知的

每个线程都有自己独立的工作区间,为了匹配CPU的运行速度,他们不会直接从内存中读取数据,而是将数据拷贝一份到CPU缓存中(即每个线程自己的工作内存),他们之间的相互交互,是通过内存来完成的。

根据JMM内存模型的8大原子操作,每个线程在j将数据操作完stroe回主存之前,会加lock指令来锁定内存区域的缓存(缓存行锁定),根据MESI缓存一致性协议,总线通过侦听器发现数据被修改,会立即让其他线程工作内存中不一致的副本立即失效。

等到当前线程将更改后的数据write回主存后,立即执行unlock指令。

此时,其他线程再重新读取更新后的数据,再拷贝到自己的工作内存。总线侦听机制会在总线上检测线程的数据,发现有线程做了更改时准备store回主内存时,它就会立刻将其他线程工作内存中的副本置位无效,然后从新到主存获取更新后的值。

除了使用 volatile 关键字来保证内存可见性之外,使用synchronized或Lock锁也能保证变量的内存可见性。只是相比而言使用 volatile关键字开销更小,是轻量级的锁。

这就是内存可见性的原理。


面试官问题:3.volatile关键字是怎么保证有序性的?什么又是重排序呢?

回答:

使用volatile关键字修饰共享变量便可以禁止指令重排序。若用volatile修饰共享变量,在JVM底层volatile是采用“内存屏障”来实现禁止特定类型的处理器重排序。加入volatile关键字时,会多出一个lock前缀指令,lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:

1.它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;

2.它会强制将对缓存的修改操作立即写入主存;

3.如果是写操作,它会导致其他CPU中对应的缓存行无效。

JMM具备一些先天的有序性,通过Happens-Before原则就可以保证的一定的有序性。


面试官问题:4.volatile能保证可见性和有序性,但是能保证原子性吗?为什么?

回答:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java帮帮 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档