volatile解决了什么问题,底层原理是什么

一、解决了什么问题

volatile 是多线程环境下的一个轻量级的同步机制,它主要解决了两个问题:内存可见性 和禁止指令重排序。它不能保证原子性。

内存可见性:
各线程从主内存读取变量到自己的工作内存,线程在自己的工作内存中更新变量,在未来的某个时间点,将修改更新到主内存中。
该过程中,若无 volatile修饰,则其它线程无法立即看到当前线程的修改。volatile修饰后,当前线程修改后强制、立即刷到主内存,且基于Happens-Before原则,volatile修饰的变量的读操作必须在写操作之后,所以其它线程可以立即看到当前线程的修改。

指令重排:
为了优化性能,编译器和处理器可能会在不改变单线程程序语义的前提下,重新排序指令的执行顺序。但在多线程环境下,这种重排序可能导致意想不到的结果
使用 volatile 修饰变量可以禁止 JVM 和处理器对相关的指令进行重排序,保证顺序上的正确性。

二、实现原理

volatile的语义是通过编译后生成的内存屏障来实现的,内存屏障本质是一类CPU指令。
JMM为volatile变量的读写提供了不同类型的内存屏障:

  1. 在每个volatile写操作之前,插入一个 StoreStore内存屏障。作用是,确保在该屏障前的所有普通写操作都刷新到主内存之后,才执行volatile写操作,这样保证了volatile修改时的内容在各线程间是一致的
  2. 在每个volatile写操作之后,插入一个StoreLoad内存屏障。作用是,确保 volatile 写操作的结果立即对其他线程可见(刷新到主内存),并且会禁止与后续的 volatile 读/写操作重排序。注意,该内存屏障的开销相比其它屏障来说,开销更大
  3. 在每个volatile读操作之后,插入LoadLoadLoadStore内存屏障。作用是,确保在执行后续的指令之前,必须先重新从主内存加载 volatile 变量的最新值。并且禁止与前面的 volatile 读操作重排序
三、和synchronized的区别
volatilesynchronized
本质JVM轻量级的关键字JVM重量级的关键字
原子性不保证原子性保证原子性
可见性保证可见性保证可见性
有序性通过禁止指令重排保证有序性通过同一时刻只有一个线程运行保证有序性
阻塞不会造成线程阻塞会造成线程阻塞
适用场景状态标志等复杂的复合操作,需要原子性的场景
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的Coder*

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值