码迷,mamicode.com
首页 > 其他好文 > 详细

volatile关键字概念

时间:2018-12-06 12:05:49      阅读:188      评论:0      收藏:0      [点我收藏+]

标签:必须   设置   获得   栅栏   long   汇编代码   相互   虚拟   静态   

一、什么是volatile关键字

  Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。

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

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

  一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,

  那么就具备了两层语义: 1、保证多线程下的可见性   2、禁止进行指令重排序(即保证有序性)。

 

二、内存模型的相关概念

(1)不同的平台,内存模型是不一样的,但是jvm的内存模型规范是统一的。

(2)线程安全无非是要控制多个线程对某个资源的有序访问或修改。

    总结:java的内存模型多线程下,要解决两个主要的问题:可见性和有序性。

(3)我们都知道计算机有高速缓存的存在,处理器并不是每次处理数据都是取内存的。

    JVM定义了自己的内存模型,屏蔽了底层平台内存管理细节。

 

三、并发编程中的三个概念

  (1)原子性:

      只有简单的读取、赋值(而且必须是将数字赋值给某个变量,变量之间的相互赋值不是原子操作)才是原子操作。

  (2)可见性:

      多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。

  (3)有序性:

      在Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。

 

五、使用volatile关键字的场景

  (1)使用valatile前后对比

  技术分享图片

 

  (2)valotile使用前提条件

      1、对变量的写操作不依赖于当前值

      2、该变量没有包含在具有其他变量的不变式中

      简单来说:就是保证该操作是原子性操作

 

六、volatile的原理和实现机制

  摘自《深入理解Java虚拟机》:

    “观察加入volatile关键字和没有加入volatile关键字时所生成的汇编代码发现,加入volatile关键字时,会多出一个lock前缀指令”

    lock前缀指令实际上相当于一个内存屏障(也成内存栅栏),内存屏障会提供3个功能:

    (1)它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;

        即在执行到内存屏障这句指令时,在它前面的操作已经全部完成。

    (2)它会强制将对缓存的修改操作立即写入主存。

    (3)如果是写操作,它会导致其他CPU中对应的缓存行无效。

  

七、synchronize与volatile的区别

技术分享图片

 八、java中能创建volatile数组吗?

   能,java中可以创建volatile数组,不过只是一个指向数组的引用,

  而不是整个数组,如果改变引用指向的数组,将会受到volatile的保护,

  但是如果多个线程同时改变数组的元素,volatile 标示符就不能起到之前的保护作用了。

 

 九、volatile能使得一个非原子操作变成原子操作吗?

  一个典型的例子是在类中有一个 long 类型的成员变量。如果你知道该成员变量会被多个线程访问,如计数器、价格等,最好是将其设置为 volatile。

  为什么?因为 Java 中读取 long 类型变量不是原子的,需要分成两步,如果一个线程正在修改该 long 变量的值,另一个线程可能只能看到该值的一半(前 32 位)。

  但是对一个 volatile 型的 long 或 double 变量的读写是原子。

 

 十、volatile 类型变量提供什么保证?

    volatile 变量提供顺序和可见性保证,

  例如,JVM 或者 JIT为了获得更好的性能会对语句重排序,但是 volatile 类型变量即使在没有同步块的情况下赋值也不会与其他语句重排序。

  volatile 提供 happens-before 的保证,确保一个线程的修改能对其他线程是可见的。

  某些情况下,volatile 还能提供原子性,如读 64 位数据类型,像 long 和 double 都不是原子的,但 volatile 类型的 double 和 long 就是原子的。

 

 

  

volatile关键字概念

标签:必须   设置   获得   栅栏   long   汇编代码   相互   虚拟   静态   

原文地址:https://www.cnblogs.com/fanhaiping/p/10075703.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!