zoukankan      html  css  js  c++  java
  • 浅谈volatile与automicInteger

    在并发环境中有三个因素需要慎重考量,原子性、可见性、有序性。
       voatile 保证了有序性(防止指令冲排序)和变量的内存可见性(每次都强制取主存数据),每次取到volatile变量一定是最新的
       volatile主要用于解决可见性,它修饰变量,相当于对当前语句前后加上了“内存栅栏”。使当前代码之前的代码不会被重排到当前代码之后,当 前代码之后的指令不会被重排到当前代码之前,一定程度保证了有序性。而volatile最主要的作用是使修改volatile修饰的变量值时会使所有线程中的缓存失效,并强制写入公共主存,保证了各个线程的一致。可以看做是轻量级的Synchronized。详情可参看:
    automicXXX主要用于解决原子性,有一个很经典的问题:i++是原子性的操作码?答案是不是,它其实是两步操作,一步是取i的值,一步是++。在取值之后如果有另外的线程去修改这个值,那么当前线程的i值就是旧数据,会影响最后的运算结果。使用automicXXX就可以非阻塞、保证原子性的对数据进行增减操作。详情可参看:http://ifeve.com/java-atomic/


    volatile原理:
        1.volatile可以保证线程可见性,且提供了一定的有序性,但无法保证原子性。
            1.保证可见性,不保证原子性
    2.禁止指令重排序
        2.JVM底层,volatile采用 "内存屏障" 来实现
        
        可见性实现:
                 可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值
         synchronize和锁都可以保证可见性。


                 线程本身并不直接与主存进行数据交换,而是通过线程的工作内存来完成相应的操作  ---  线程间数据不可见的根本原因!!!
         volatile实现可见性,直接从这方面入手,
            1.修改volatile变量时,会强制将修改后的值刷新到主内存中
    2.修改volatile变量后,会导致其他线程工作内存中对应的变量值失效,再读取该变量值时,要重新从主内存中读取


        有序性实现:
                 关于重排序:
              编译器重排序:不改变单线程语义的前提下,可以重新安排语句的执行顺序
      处理器重排序:不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序
                 指令重排序对单线程无影响,但会影响多线程的正确性,
         JVM如何禁止重排序?
               happens-before 原则:保证程序的有序性
    ---------------------
    作者:拉萨之虎2012
    来源:CSDN
    原文:https://blog.csdn.net/dan1289095756/article/details/80803977
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    MongoDB 删除文档
    MongoDB 删除文档
    C#标记 [已弃用] 的方法
    C#标记 [已弃用] 的方法
    MySQL 正则表达式
    MySQL 正则表达式
    SQLcase when then用法
    SQLcase when then用法
    衣服尺码自定义排序sql
    衣服尺码自定义排序sql
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/10225694.html
Copyright © 2011-2022 走看看