4年开发二面美团最终败给:volatile关键字作用和原理这道面试题

简介: 一位6年工作经验的小伙伴,在某里二面的时候被问到“volatile”关键字。然后,就没有然后了…同样,还有一位4年的小伙伴,去某团面试也被问到“volatile 关键字“。然后,也没有然后了…volatile关键字是Java并发编程中的一个重要的关键字,这个问题确实问得比较底层了。难道大厂现在都这么卷了吗?那今天呢,我给大家分享一下我的理解,希望能够帮助到大家。

一位6年工作经验的小伙伴,在某里二面的时候被问到“volatile”关键字。然后,就没有然后了…


同样,还有一位4年的小伙伴,去某团面试也被问到“volatile 关键字“。然后,也没有然后了…


volatile关键字是Java并发编程中的一个重要的关键字,这个问题确实问得比较底层了。难道大厂现在都这么卷了吗?那今天呢,我给大家分享一下我的理解,希望能够帮助到大家。


另外,我准备了一份500页的PDF面试题解析配套文档,

如何获取? :

扫描文章底部二维码领取!

1、volatile的作用

volatile 关键字呢,有两个作用:

e89c5326a7f5b8308bf3e9c9eb6e6f4c.png

第1个,是可以保证在多线程环境下共享变量的可见性。

第2个,是可以屏蔽在多线程环境下CPU的指令重排。

下面,我给大家详细介绍一下可见性和屏蔽指令重排以及volatile的工作原理。

2、原理分析

先来看变量的可见性,简单来说,就是指当某一个线程对共享变量的修改,其他线程可以立刻看到修改之后的值。其实这个可见性问题,我认为本质上是由以下两个方面造成的。

首先是,CPU的高速缓存。在 CPU 里面设计了三级缓存去解决 CPU 运算效率和内存 IO 效率问题,但是有带来了缓存的一致性问题,而在多线程并行执行的情况下,缓存一致性就会导致可见性问题。

0a00e2a1ee6e0fe9283f9949a3a61bae.png

所以,对于增加了 volatile 关键字修饰的共享变量,JVM 虚拟机会自动增加一个#Lock 汇编指令,这个指令会根据 CPU 型号自动添加总线锁或/缓存锁。

我简单介绍一下这两种锁:

总线锁是锁定了 CPU 的前端总线,从而导致在同一时刻只能有一个线程去和内存通信,这样就避免了多线程并发造成的可见性。

缓存锁是对总线锁的优化,因为总线锁导致了 CPU 的使用效率大幅度下降,所以缓存锁只针对 CPU 三级缓存中的目标数据加锁,缓存锁是使用 MESI 缓存一致性来实现的。

然后,就是屏蔽指令重排,就是指屏蔽CPU指令重排序。意思是在多线程环境下,CPU指令的编写顺序和执行顺序不一致,从而导致可见性问题,为了提升 CPU 的利用率,CPU引入了StoreBuffer 机制,而这一种优化机制会导致 CPU 的乱序执行。当然为了避免这样的问题,CPU 提供了内存屏障指令,上层应用可以在合适的地方插入内存屏障来避免 CPU 指令重排序问题。而volatile就是通过设置内存屏障来禁止指令重排。

volatile内存屏障实现原理主要从以下两个方面来分析:

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

093642cef1f579d48b34da2c5555d779.png

第2个是:volatile在变量的读操作后面插入两个指令,禁止后面的读指令和写指令重排序。,如图所示:

dc4d314802c033ada19b16efaac68613.png

volatile其实可以看作是轻量级的synchronized,虽然说volatile不能保证原子性,但是如果在多线程下的操作本身就是原子性操作(例如赋值操作),那么使用volatile会优于synchronized。以上就是我对volatile 关键字的理解。

并发编程是每个程序员必须要掌握好的领域,它里面涵盖的设计思想、和并发问题的解决思路、以及作为一个并发工具,都是非常值得深度研究的。

最后,我把往期分享的视频全部整理成了1份20W字的文档,希望能够以此来提高各位粉丝的通过率

ee90d9963df444db88b33d6e798a5b94.gif

我是被编程耽误的文艺Tom,只弹干货不掺水!你们的支持就是我最大的动力!关注我,面试不再难!

相关文章
|
6天前
|
安全 Java 数据库
一天十道Java面试题----第四天(线程池复用的原理------>spring事务的实现方式原理以及隔离级别)
这篇文章是关于Java面试题的笔记,涵盖了线程池复用原理、Spring框架基础、AOP和IOC概念、Bean生命周期和作用域、单例Bean的线程安全性、Spring中使用的设计模式、以及Spring事务的实现方式和隔离级别等知识点。
|
6天前
|
缓存 安全 Java
面试官:说说volatile应用和实现原理?
面试官:说说volatile应用和实现原理?
16 1
|
10天前
|
消息中间件 算法 前端开发
京东面试:说说CMS工作原理?
京东面试:说说CMS工作原理?
27 2
|
1月前
|
SQL 安全 Java
Android经典面试题之Kotlin中object关键字实现的是什么类型的单例模式?原理是什么?怎么实现双重检验锁单例模式?
Kotlin 单例模式概览 在 Kotlin 中,`object` 关键字轻松实现单例,提供线程安全的“饿汉式”单例。例如: 要延迟初始化,可使用 `companion object` 和 `lazy` 委托: 对于参数化的线程安全单例,结合 `@Volatile` 和 `synchronized`
29 6
|
7天前
|
缓存 Java 编译器
一文搞懂volatile面试题
这篇文章是关于Java关键字volatile的详细介绍和分析,volatile是多线程访问共享变量时保证一致性的方案,性能优于synchronized,但不保证操作原子性,需要同步处理。
|
12天前
|
Java 开发工具 Android开发
Android经典面试题之开发中常见的内存泄漏,以及如何避免和防范
本文介绍Android开发中内存泄漏的概念及其危害,并列举了四种常见泄漏原因:静态变量持有Context、非静态内部类、资源未释放及监听器未注销。提供了具体代码示例和防范措施,如使用ApplicationContext、弱引用、适时释放资源及利用工具检测泄漏。通过遵循这些建议,开发者可以有效提高应用稳定性和性能。
22 0
|
1月前
|
缓存 监控 算法
Java面试题:描述Java垃圾回收的基本原理,以及如何通过代码优化来协助垃圾回收器的工作
Java面试题:描述Java垃圾回收的基本原理,以及如何通过代码优化来协助垃圾回收器的工作
57 8
|
1月前
|
缓存 安全 Java
Java面试题:解释volatile关键字的作用,以及它如何保证内存的可见性
Java面试题:解释volatile关键字的作用,以及它如何保证内存的可见性
41 4
|
1月前
|
安全 Java
Java面试题:解释synchronized关键字在Java内存模型中的语义
Java面试题:解释synchronized关键字在Java内存模型中的语义
33 1