面试题:volatile关键词是什么?

一、概述

volatile可以看作是轻量级的synchronized,volatile不会引起线程的上下文切换和调度,但是却可以在多处理器开发中保证了共享变量的“可见性”。(当一个线程修改一个共享变量时,另一个线程可以读到这个修改的值)

二、为什么要使用volatile

java内存模型规定所有的变量都存放在主内存当中,每个线程在执行的时候,会从主内存当中拷贝一份到自己的工作内存当中,线程对变量的读取,操作都是在工作内存当中执行的。

不同线程之间也不能相互访问其他线程的工作内存,那么线程之间的变量传递需要通过主内存来实现共享。

如果不能及时将修改过的变量更新到主内存当中去,就有可能会导致数据的不一致的情况。

而volatile关键字就是为了解决数据一致性的问题,当线程A对变量的修改后,变量会直接刷新到主内存。这时线程B在对变量进行读取的时,如果变量是volatile关键字修饰的变量,则直接放弃从工作内存当中读取,而是从主内存中读取。

三、原理

当把变量声明为volatile类型后,编译器会注意到这个变量是共享的,不会将该变量上的操作与其他内存操作一起重排序。

volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。

四、面试题考点

1)性能问题

volatile 的读性能消耗与普通变量几乎相同,但是写操作稍慢,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。

2)原子性

volatile不能保证原子性,如果想要保证原子性,可以使用synchronized关键字或者lock加锁

3)指令重排序

CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理,volatile可用于禁止指令重排序优化,有volatile修饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,增加一个内存屏障。

两个操作都有volatile要求的,一定不能重排序指令。

如果volatile写操作,即便前面是普通写操作,为了保证主存数据是后面操作的结果也不能重排序

如果是volatile读操作,因为后面的普通写操作可能会刷新主存,为了保证百分百执行结果的正确不能重排序

发布了43 篇原创文章 · 获赞 0 · 访问量 3897

猜你喜欢

转载自blog.csdn.net/zhangdx001/article/details/105275486