为什么单例模式懒汉式doublecheck要使用volatile关键字修饰

为什么单例模式懒汉式doublecheck要使用volatile关键字修饰

public class SingletonTest06 {
    public static void main(String[] args) {
        //测试
        Singleton instance = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance == instance2); // true
        System.out.println(" instance.hashCode=" + instance.hashCode());
        System.out.println(" instance2.hashCode=" + instance2.hashCode());
    }

    //懒汉式(线程安全,同步方法)
    static class Singleton {
        private static volatile Singleton instance;

        private Singleton() {
        }

        //提供一个静态的公有方法,加入双重检查代码,解决线程安全问题,同时解决懒加载问题/同时保证了效率,推荐使用
        public static synchronized Singleton getInstance() {
            if (instance == null) {
                synchronized (Singleton.class) {
                    if (instance == null) {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
}
instance = new Singleton();

这一步实际的操作可被分为了三步:

1分配内存空间属性赋默认初始值(0、false等0值);

2属性赋初值或构造函数值(赋真实值);

3将instance位置指向此处内存空间;

​ 但是这三步有可能被cpu进行指重排序,导致线程1在创建instance时先1后3(则此时singleton已有null变为有真正的指向),若这时线程2得到cup进来了发现singleton已不为null,便将其拿入工作副本实用,则会出现问题;这种概率极小但一旦发生在某些业务中可能就是致命的,所以此处需要禁止指令重排序,而volatile便有这个功能(可见性,禁止指令重排序)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值