volatile关键字原理详解

volatile关键字原理解析

​ volatile,Java保证并发的一种手段,Java为了保证并发提供了一系列并发机制:synchronized、ReentrantLock、volatile,其中volatile是最轻量级的锁。为什么这么说呢?下面将详细介绍,首先说一下Java同步的三大特性:

  • 原子性:顾名思义,每一个操作都是最小的不可分割的单元
  • 可见性:当前线程的操作对其他线程是可见的
  • 有序性:每一个原子操作的执行顺序是有序的

这三大特性synchronized锁全部满足,而volatile则只满足可见性和有序性。不保证原子性操作,因此相比肯定比synchronized更加的轻量。

1 可见性

​ JMM(Java内存模型)规定:每个线程都有自己的工作区,所有变量都放在主内存中,当线程要对变量操作时首先将主内存中的变量拷贝到工作内存中,利用CAS来进行写操作。至于如何保证对其他处理器是可见的,以Intel处理器为例,当当前线程将变量写会主内存中,当前线程和主内存之间的总线会有一个缓存一致性协议(EMSI)来使其他处理器中该变量值失效,因此保证了可见性。但讲缓存一致性协议貌似和volatile离远了,我们对一个volatile关键字修饰的变量进行反编译,会发现其在汇编层面上会加一个lock前缀,通过查IA-32架构软件开发者手册可知Lock指令在多核处理器下会引发两件事情:

  • 将当前处理器缓存行的数据写会到系统主内存。

  • 这个写回内存的操作会使在其他CPU里缓存了该内存地址的数据无效。

    ​ 在多处理器下,为了保证各个处理器的缓存是一致的,就会实现缓存一致性协议,每个处理器通过嗅探在总线上传播的数据来检查自己缓存的是不是过期了,当处理器发现自己缓存的内存地址被修改,就会将当前处理器的缓存行设置成无效状态,下次修改时又会重新从系统内存中读取。

    ​ 因此对于可见性,我们只需要知道lock操作会引起其他线程的缓存失效,并不需要去关心每个处理器是通过什么协议(如EMSI)来实现的。

2 有序性

​ 在JVM层面上,保证有序性是通过内存屏障(memory barriers)来实现的,即进制指令进行重排序优化。内存屏障有:

  • LoadLoad屏障:对于Load1;LoadLoad;Load2指令,保证在Load2及后续操作开始前,Load1的读取操作已经全部完成。
  • LoadStore屏障:对于Load1;LoadStore;Store1指令,保证在Store1及后续操作开始前,Load1的读取操作已经全部完成。
  • StoreStore屏障:对于Store1;StoreStore;Store2指令,保证在Store2及后续操作开始前,Store1的操作对其他处理器是可见的。
  • StoreLoad屏障:对于Store1;StoreLoad;Load1指令,保证在Load1及后续操作开始前,Store1的操作对其他处理器是可见的。

3 Volatile的常见问题

3.1 谈一谈你对volatile的理解

答:从可见性和有序性聊起就行。

3.2 volatile为什么不保证原子性

答:以典型例子i++来说,两个线程都对num=0进行加1操作,而线程1先到达总线,那么线程执行写操作时会失败,因此再重新读取进行写入,此时num=2,但是显然循环了3次,因此它不保证原子性。而保证原子性的手段有

  1. 使用总线锁保证原子性,即为处理器提供一个Lock#信号,当一个处理器在总线上输出此信号时,其他处理的请求将被阻塞住。
  2. 使用缓存锁来保证原子性,即在同一时刻我们只需保证对某个内存地址的操作是原子性的即可。
  3. Java中可以通过锁和循环CAS来实现原子操作。

AtomicInteger保证,找它去。

3.3 JMM内存模型讲一下

答:变量存储在主内存中,每个线程都有自己的工作内存。采用CAS来完成操作,按照这个步骤讲就行,八大原子操作(read、load、use、assign、store、write、lock、unlock)。

3.4 DCL单例要不要加volatile关键字

答:一定要加!要保证进制指令重排序,因为对象的创建过程中会发生指令重排序,我们要通过volatile来避免。

4 与synchronized比较

​ 二者是互补的存在,而不是为了取代谁。

  • volatile关键字是线程同步的最轻量级实现,所以性能好,但是它只能用于变量而synchronized可以修饰方法和代码块。
  • volatile能保证数据的可见性,但不保证原子性。
  • volatile关键字主要用于解决变量在多线程的可见性,而synchronized关键字解决的是多个线程之间访问资源的同步性。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值