面试大杀器之:给我说说:volatile

原因就是flag初始的时候,初始值会加载进主内存,再由主内存写进本地内存,线程A执行时就会一直读本地内存,尽管线程B抢占了线程,将主内存的flag赋值未false,但是线程A由于执行太快,并不会在执行之前将主内存的值实时更新进线程A的本地内存。种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。
摘要由CSDN通过智能技术生成

在我们学习并发时,有一个关键词是任何时候都没有办法绕过去的!没错,volatile。很多人对volatile的认知还停留在概念上,殊不知,你说的这些,都不是面试官希望了解的,概念谁不知道,想知道的是为什么。好的,今天由我给大家带来volatile史上最刨根问底的面试问题,看看你能挺到第几关?

volatile的特性

可见性:对一个volatile变量的读,①总是能看到(任意线程)对这个volatile变量最后的写入

原子性:对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性(基于这点,我们通过会认为volatile不具备原子性)。volatile仅仅保证对单个volatile变量 的读/写具有原子性,而锁的互斥执行的特性可以确保对整个临界区代码的执行具有原子性。

64位的long型和double型变量,只要它是volatile变量,对该变量的读/写就具有原子性。

有序性:对volatile修饰的变量的读写操作前后加上各种特定的②内存屏障来禁止③指令重排序来保障有序性。

如果您面试的是一个相当不错的自研公司,你在面试官面前回答这三点时,那么恭喜您,您将迎来一系列狂风暴雨式的追问,此时就是你表现自我的一次机会!

追问:

1、为什么可以总是能看到(任意线程)对这个volatile变量最后的写入

2、什么是内存屏障

3、什么是指令重排?为什么要设计指令重排?你能给我简单分析一个因为指令重排这个原因而可能导致的bug吗?

如果,您有幸被追问以上几个问题,并且可以对答如流,那么恭喜你,此轮面试,您将会在面试官的心里打上高分!

想把以上问题解释清楚,是十分考验一个程序猿的综合实力的,并不是几分钟可以说的清楚的。

你问我为什么?那就让我一一道来!

  1. 为什么可以总是能看到(任意线程)对这个volatile变量最后的写入

想说清楚这个问题,就不得不请出一个大名鼎鼎的java模型:JMM模型

是的!我没有写错,很多基础不好的同学,会以为我把JVM写成了JMM,其实这个是两个不同的模型。JVM模型,也是大厂的热点问题,但不是今天的主角。接下来有请JMM!!!看图:

 

ava虚拟机规范中定义了Java内存模型(Java Memory Model,JMM),用于屏蔽掉各

种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果,JMM规范了Java虚拟机与计算机内存是如何协同工作的:规定了一个线程如何和何时可以看到由其他线程修改过后的共享变量的值,以及在必须时如何同步的访问共享变量。JMM描述的是一种抽象的概念,一组规则,通过这组规则控制程序中各个变量在共享数据区域和私有数据区域的访问方式,JMM是围绕原子性、有序性、可见性展开的

现在给大家分析一下此图:JMM模型最关键的两点:本地内存和主内存,这也是回答的重点。

解析上图:

假设有两条线程ThreadA和ThreadB,未做任何特殊处理时,同时对全局变量布尔:flag进行操作。设置flag的初始值时true。线程A是一个while(flag)循环。线程B把flag,设置成为false。

在这种情况下,很多同学就会分析了,认为while循环执行是有数的,不会一直执行下去,因为线程B一旦抢占了执行,就会把flag的值更改!其实不然,当你在了解jmm模型的时候,便会颠覆你的认知,当不做任何处理时while会进入死循环。原因就是flag初始的时候,初始值会加载进主内存,再由主内存写进本地内存,线程A执行时就会一直读本地内存,尽管线程B抢占了线程,将主内存的flag赋值未false,但是线程A由于执行太快,并不会在执行之前将主内存的值实时更新进线程A的本地内存。导致while会一直执行下去!

JMM与硬件内存架构的关系

Java内存模型与硬件内存架构之间存在差异。硬件内存架构没有区分线程栈和堆。对于硬

件,所有的线程栈和堆都分布在主内存中。部分线程栈和堆可能有时候会出现在CPU缓存中和CPU内部的寄存器中。如下图所示,Java内存模型和计算机硬件内存架构是一个交叉关系:

 

回到上述问题,如果一开始在  Boolean flag

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值