美文网首页
9.volatile、final

9.volatile、final

作者: 段段小胖砸 | 来源:发表于2021-09-01 17:02 被阅读0次

    1.变量写入原子性问题

    long和double是64位的,当32位的机器上为这两种类型变量赋值,可能被拆分成两个32位的写操作来执行。解决办法:在long前面加上volatile关键字

    2.重排序:DCL问题

    单例模式的线程安全的写法不止一种,常用写法为DCL(Double Checking Locking)

    public class Singleton { 
        private static Singleton instance; 
        public static Singleton getInstance() {
            if (instance == null) { 
                synchronized(Singleton.class) { 
                    if (instance == null) { 
                        // 此处代码有问题 
                        instance = new Singleton(); 
                    } 
                } 
            }
          return instance; 
        } 
    }
    

    根据上一个章节的jmm模型中的重排序问题可知,会出现如下情况

    1. 分配一块内存。
    2. 在内存上初始化成员变量。
    3. 把instance引用指向内存。

    操作2和操作3可能重排序,即先把instance指向内存,再初始化成员变量,因为二者并没有先后的依赖关系。此时,另外一个线程可能拿到一个未完全初始化的对象。这时,直接访问里面的成员变量,就可能出错。

    解决办法:就是为instance变量加上volatile修饰。

    3.volatile实现原理

    1. 在volatile写操作的前面插入一个StoreStore屏障。保证volatile写操作不会和之前的写操作重排序。
    2. 在volatile写操作的后面插入一个StoreLoad屏障。保证volatile写操作不会和之后的读操作重排序。
    3. 在volatile读操作的后面插入一个LoadLoad屏障+LoadStore屏障。保证volatile读操作不会和之后的读操作、写操作重排序

    final

    public class MyClass { 
        private int num1; 
        private int num2; 
        private static MyClass myClass; 
        public MyClass() {
         num1 = 1; num2 = 2; 
        }
        /*** 线程A先执行write() */ 
        public static void write() { 
            myClass = new MyClass(); 
        }
        /*** 线程B接着执行write() */ 
        public static void read() { 
            if (myClass != null) { 
                int num3 = myClass.num1;
                int num4 = myClass.num2; 
            } 
        }
     }
    

    和DCL的例子类似,myClass = new MyClass()这行代码,分解成三个操作:

    1. 分配一块内存;
    2. 在内存上初始化i=1,j=2;
    3. 把myClass指向这块内存。
      操作2和操作3可能重排序,因此线程B可能看到未正确初始化的值。

    解决办法:
    办法1:给num1,num2加上volatile关键字。
    办法2:为read/write方法都加上synchronized关键字。
    办法3:如果num1,num2只需要初始化一次,还可以使用final关键字。

    相关文章

      网友评论

          本文标题:9.volatile、final

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