zoukankan      html  css  js  c++  java
  • volatile

    volatile 的主要作用有两个方面【可见性/顺序性[防止指令重排序]】

    可见性:

    首先熟悉一下JVM的内存工作模型[注意这里的工作模型不是堆/栈/方法区这些],

    线程本身并不直接与主内存进行数据的交互,而是通过线程的工作内存来完成相应的操作。这也是导致线程间数据不可见的本质原因。因此要实现volatile变量的可见性,直接从这方面入手即可。对volatile变量的写操作与普通变量的主要区别有两点:1 修改volatile变量时会强制将修改后的值刷新的主内存中。 2 修改volatile变量后会导致其他线程工作内存中对应的变量值失效。因此,再读取该变量值的时候就需要重新从读取主内存中的值。通过这两点就可以很好的解决可见性问题。
     
    顺序性[防止指令重排序]:
    volatile之所以能够阻止指令重排,是因为底层JVM里面利用了内存屏障来实现的,内存屏障主要有三点功能:
    1. 它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;
    2. 它会强制将对缓存的修改操作立即写入主存;
    3. 如果是写操作,它会导致其他CPU中对应的缓存行无效。

    举个栗子:

    public class Singleton {
        public static volatile Singleton instance = null;
        private Singleton() {
        }
        public static Singleton getInstance() {
            if (instance == null) {
                synchronized (instance) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    
    双重校验的写法:第一次判断是否为null是为了拒绝掉当对象不为空的时候剩余的线程。里面加锁是为了当对象为null的时候,此时同时进来两个线程(A和B两个线程),我们要保证只有一个线程才可以初始化对象,所以在这里面加上了锁,这样A拿到了锁进去初始化对象,然后进行返回,B再进去此时发现不为null,那么就不执行初始化的过程。这样就能保证上面的单例模式的正常运行,同时为系统也是节约了许多开销(避免每个线程进来加锁--懒汉式写法)
     
    并发编程中谈及到的无非是可见性、有序性及原子性,为什么volatile不能保障原子性?
    因为 volatile 只能修饰变量,但是有些变量的操作就没办法保障了,比如 i++  ,看JVM变异的指令其实是多条语句的,所以不能保障原子性,只能通过加锁的形式帮助去解决。
     
     
     
  • 相关阅读:
    Datawhale编程实践(LeetCode 腾讯精选练习50)Task2
    Datawhale编程实践(LeetCode 腾讯精选练习50)Task1
    关于深度学习中样本权重取0的问题
    对多维numpy数组使用random.shuffle的问题
    Ubuntu18.04LTS左上角光标闪烁原因之一:NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver.
    pycharm 报错ImportError: could not import module 'PySide2.QtWidgets'
    pyinstaller 打包pyside2项目遇到plugins window问题
    git pull的时候出错: Git Couldn't reserve space for cygwin's heap
    angularjs鼠标移入移出实现显示隐藏
    gulp编译出现Cannot find module 'internal/util/types'——node环境的变更
  • 原文地址:https://www.cnblogs.com/junbaba/p/14131412.html
Copyright © 2011-2022 走看看