重排序与volatile

重排序

为了提高编译器和处理器的能力,对代码编译执行顺序进行修改

// a和b没有依赖关系,编译时可能会是b先执行在执行a
int a = 1
int b = 2 
// 下面由于b依赖于a,所以不会进行重排序
int a = 1
int b = a + 1

volatile

当一个线程对共享变量进行修改,其他线程可以立即知道新的共享变量的值,防止重排序

  1. 每次使用时立即从主内存刷新
  2. read,load,use必须连续出现
  3. assign,store,write必须连续出现

双检锁单例模式

mInstance没有被volatile修饰是不正确的
当线程A调用getInstance方法时,走到第4步,有可能会发生重排序
第4步的执行可分为
1. 分配一块内存
2. 初始化
3. mInstance指向这块内存
发生重排序上面顺序有可能1,3,2
如果此时线程B也来调用getInstance方法,在mInstance== null时正好线程A走到了“mInstance指向这块内存”,此时mInstance不为null,但还没有初始化。线程B拿到的就是有问题的引用

public class Singleton {
     // 正确写法private static  volatile Singleton mInstance;
    private static Singleton mInstance;
    private Singleton(){
    }
    public static Singleton getInstance(){
        if(mInstance== null){                                  // 第1步
            synchronized(Singleton.class){                     // 第2步
                if(mInstance== null){                          // 第3步
                    mInstance= new Singleton();                // 第4步
                } 
            }
        }
        return mInstance;                                      // 第5步
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值