volatile关键字在多线程中的使用

一、关于volatile

关键字volatile是Java虚拟机提供的最轻量级的同步机制,但是它并不容易被正确的、完整的理解,以至于许多程序员都不习惯去用它,遇到需要处理多线程数据竞争的问题一律使用synchronized来进行同步。

二、volatile的特性

当一个变量被定义成volatile之后,它具备两种特性:

1、保证此变量对所有线程的可见性

2、禁止指令重排序优化

三、特性一之可见性

这里的可见性是指当一条线程修改了这个变量的值,新值对于其他线程是可以立即得知的。对于普通变量来说,不能做到这一点,变量值在线程间传递均需要主内存来完成。但是不能保证的是:基于volatile变量的运算在并发下是安全的。volatile变量在各个线程的工作内存中不存在一致性问题,这里的不一致问题是volatile变量在各个线程的工作内存中,每次使用之前都要刷新,执行引擎看不到不一致的情况,因此可以认为不存在一致性的问题。但是Java里面的运算并非原子操作,导致volatile变量的运算在并发下是一样是不安全的。

由于volatile变量只能保证可见性,我们可以在符合以下两条规则的运算情况下使用它:1、变量结果并不依赖变量的当前值,或者确保只有单一的线程修改变量的值

2、变量不需要与其他的状态变量共同参与不变约束

如果不能符合以上两个条件,我们仍然需要通过加锁(使用synchronized或者java.util.concurrent中的原子类)来保证原子性。

四、特性二之禁止指令重排序优化

普通的变量仅仅会保证在该方法执行的过程中所有依赖赋值结果的地方都能获取到正确的结果,而不能保证变量赋值操作的顺序与程序代码中的执行顺序一致。使用volatile修饰的变量可以保证执行顺序。

五、使用volatile的意义

在某些情况下,volatile同步机制的性能要优于锁(使用synchronized关键字或者其它锁),但是虚拟机对锁实行的许多消除和优化,使得我们很难量化的说volatile就会比synchronized快上多少。volatile变量读操作的性能消耗和普通变量的几乎没有什么差别,但是写操作可能会慢上一些,因为它需要在本地代码中插入许多内存屏蔽指令来保证处理器不发生乱序执行。在大多数场景下volatile的总开销仍然要比锁来的低,我们在volatile与锁中选择的唯一判断依据仅仅是volatile的语义能否满足使用场景的需求。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

猿人小郑

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

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

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

打赏作者

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

抵扣说明:

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

余额充值