DCL单例模式中,为什么要加volatile?

DCL单例模式中,为什么要加volatile?

DCL:double check lock双重检查锁,如下面的代码

public class Singleton {
    private static volatile Singleton INSTANCE = null;
    private Singleton(){}
    public static Singleton getInstance(){
        if(INSTANCE==null){//第一次检查
            synchronized (Singleton.class){
                if(INSTANCE==null){//第二次检查
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }
}
为什么要加两次判空,第一次判空能不能不加?

效率问题:假设第一次判空不加,那么每次进入这个方法,INSTANCE不论是不是null,都会执行下面的synchronized代码块,多线程下会出现锁的竞争,而除了第一次初始化,后面的都不会为null,判空的效率比加锁高。

为什么要进行第二次判空?

防止多次初始化:多线程下,有可能会出现两个线程都经过了前面第一次检查,来到了下面的synchronized这里,如果不判空,就会出现一个线程new了一个Singleton出来,然后释放锁,第二个线程进来又会new一个Singleton出来。

volatile能不能不加?

volatile作用:

  1. 保持内存可见性
  2. 防止指令重排序
    volatile这里的作用就是防止指令重排INSTANCE = new Singleton();这一行主要做了下面几件事:
  3. 在内存中开辟空间
  4. 执行构造方法初始化对象
  5. 将对象的引用赋值给INSTANCE变量
    在不加volatile的情况下,第2和第3步是有可能发生指令重排的,即执行顺序变成了1、3、2,假如我刚好执行到第3步,还没执行第2步,这时候另外一个线程调了这个方法,获取到的是还没执行初始化函数的对象,在上面的代码中,初始化函数什么都没做,所以没什么影响。但是如果初始化函数中需要做一些操作,那就有影响了。

最近为了督促自己学习,搞了个公众号,算是自己平时的学习笔记,以后面试的时候看一看。有兴趣的可以微信搜索序员说公众号,每天花五分钟跟我一起学习,或者发送消息分享下工作、生活的事情也行。扫下面二维码添加公众号啊!!!在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值