Java volatile

作者: 韭菜待收割 | 来源:发表于2018-09-26 10:11 被阅读4次

    1、volatile关键字的作用

    用于保持内存可见性(随时见到的都是最新值)和防止指令重排序。

    2、volatile如何保持内存可见性

    内存可见性:所有线程都能看到共享内存的最新状态。

    Java通过几种原子操作完成工作内存和主内存的交互:
    lock:作用于主内存,把变量标识为线程独占状态。
    unlock:作用于主内存,解除独占状态。
    read:作用主内存,把一个变量的值从主内存传输到线程的工作内存。
    load:作用于工作内存,把read操作传过来的变量值放入工作内存的变量副本中。
    use:作用工作内存,把工作内存当中的一个变量值传给执行引擎。
    assign:作用工作内存,把一个从执行引擎接收到的值赋值给工作内存的变量。
    store:作用于工作内存的变量,把工作内存的一个变量的值传送到主内存中。
    write:作用于主内存的变量,把store操作传来的变量的值放入主内存的变量中。

    volatile的特殊规则就是:
    read、load、use或者assign、store、write动作必须连续出现。
    使用volatile变量能够保证:每次读取前必须先从主内存刷新最新的值。每次写入后必须立即同步回主内存当中。

    3、volatile如何防止指令重排

    防止指令重排:在基于偏序关系的Happens-Before内存模型中,指令重排技术大大提高了程序执行效率。
    volatile关键字通过"内存屏障"来防止指令被重排序。
    为了实现volatile的内存语义,编译器在生成字节码时,会在指令序列中插入内存屏障来禁止特定类型的处理器重排序。

    //懒加载示例
    class Singleton {
        private static Singleton instance;
        private Singleton(){}
        public static Singleton getInstance() {
                //当instance不为null时,仍可能指向一个"被部分初始化的对象"
                //需要用volatile来修饰instance避免发生指令重排序
            if ( instance == null ) { 
                synchronized (Singleton.class) {
                    if ( instance == null ) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    

    参考https://www.cnblogs.com/shan1393/p/8999683.html

    相关文章

      网友评论

        本文标题:Java volatile

        本文链接:https://www.haomeiwen.com/subject/uihdoftx.html