zoukankan      html  css  js  c++  java
  • volatile理解

    多线程程序常考虑三种性质:原子性、可见性、有序性。定义如下:

     1. 原子性:
           一个或多个操作的执行,只有两种情况:(1)全部执行并且执行过程中不会被打断;(2)不执行
     2. 可见性:
            当多个线程访问同一个共享变量时,一个线程修改了变量的值,其他线程能够立即看到被修改的新值。 例如:
                 //线程1执行的代码  
                    int i = 0;  
                    i = 10;  
                 //线程2执行的代码  
                    j = i;

            当线程1执行完i=10时,其过程是:将i的初始值读入高速缓存中,然后讲高速缓存中 i 的值改为10,再将i的新值刷入内存中;

            若没有可见性,则i的新值未刷入主存时,线程2执行,此时线程2读取内存中的 i 的值为0。(线程1修改了 i 值,线程2没有立即看到)

     3. 有序性:

            程序执行的顺序按照代码中的先后顺序执行。

            为了提高程序效率,编译器会对代码进行优化,将没有依赖关系的指令执行先后顺序进行重排,使指令执行顺序与代码先后顺序不同,但保 证最终的结果一致。虽然指令重排对单线程没有影响,但会影响多线程并发执行的正确性。

    在JAVA中实现三种性质的方式:

       原子性是通过同步(Synchronized或Lock锁机制)来实现;

           可见性是通过volatile来实现(保证变量修改后立即写入内存);

           有序性是通过同步或volatile来实现。

    volatile的特性与作用:

     1. volatile修饰变量后的特性:

              (1)保证了多个线程对变量操作的可见性,即:一个线程修改了变量值,其他线程立即可见。(保证变量安全,不保证线程安全)

              (2)禁止进行指令重排。(防止编译器自动优化,对代码顺序的指令重新排序)    

     2. volatile保证变量可见性:

              (1)使用volatile修饰的变量,在一个线程中被修改后会强制立即写入内存(不经过线程工作内存,即线程中的寄存器或堆栈空间);

              (2)使用volatile修饰的变量,当有线程修改其值后,其他线程的工作内存中该值无效;

              (3)使用volatile修饰的变量,所有线程必须从内存读取变量值(不经过线程工作内存,即该线程的寄存器或堆栈空间)。  

     3. volatile不保证变量原子性:

               某些情况下,volatile可以实现变量原子性,如:long和double都是64位宽,32位操作系统对这种类型变量的读取分两部分,第一次读取32位,第二次读取剩下的32位。读取操作不是原子性的,当用volatile修饰(volatile long)时,可以将操作变为原子性操作。

     4. volatile保证变量有序性:

               使用volatile修饰的变量,编译器不能对该变量所在指令重排(例如:该指令之前的指令集合相互可以重排,但不能重排到该指令后面)

  • 相关阅读:
    Alpha版与Beta版
    URL的概念
    正则表达式(即:匹配模式Pattern)
    前置与后置的递增/递减操作符
    【平板电脑模拟器】PC端-Chrome自带的功能
    【HOSTS相关】前端提供测试模板地址
    【netlimiter】的使用
    <转>window.event对象在ie与ff中的区别
    <转>全面理解javascript的caller,callee,call,apply概念(修改版)
    document.styleSheets以及js中实现样式表的切换、样式的增加减少
  • 原文地址:https://www.cnblogs.com/ladawn/p/8253531.html
Copyright © 2011-2022 走看看