Lazy singleton中的double check

单例模式的三个必要条件:私有静态成员变量(这个类的引用),私有函数,获取这个静态成员变量的方法

一是某个类只能有一个实例;
二是它必须自行创建这个实例;
三是它必须自行向整个系统提供这个实例。

写eagersingleton时候,你可能这样写:

public class EagerSingleton {
    private static final EagerSingleton SINGLETON = new EagerSingleton();

    private EagerSingleton() {
    }

    public static EagerSingleton getSingleton() {
        return SINGLETON;
    }
}

你是不是在想,lazysingleton可以模仿eagersingleton:

public class LazySingleton {
    private static LazySingleton singleton = null;

    private LazySingleton() {
        System.out.println("构造函数被调用");
    }

    public static LazySingleton getSingleton() {
        if (singleton == null) {
            singleton = new LazySingleton();
        }
        return singleton;
    }
}

很明确地告诉你,这中写法不符合singleton的要求,为什么?Let me show you now

当遇到多线程的时候,就出问题了,看图吧
这里写图片描述

那简单啊,在getSingleton()方法前面加个锁就解决问题了:

public class LazySingleton {
    private static LazySingleton singleton = null;

    private LazySingleton() {
        System.out.println("构造函数被调用");
    }

    synchronized public static LazySingleton getSingleton() {
        if (singleton == null) {
            singleton = new LazySingleton();
        }
        return singleton;
    }
}

的确问题解决了,但是这样貌似不太好。因为每次调用的getSingleton()方法的时候都会进行线程锁定判断,在多线程高并发的条件下,将会导致系统的性能大大降低。

最终的解决办法是,double check:

public class LazySingleton {
    private static LazySingleton SINGLETON = null;

    private LazySingleton() {
        System.out.println("构造函数被调用");
    }

    public static LazySingleton getSingleton() {
        // 1st check
        if (SINGLETON == null) {
            synchronized (LazySingleton.class) {
                // 2nd check
                if (SINGLETON == null) {
                    SINGLETON = new LazySingleton();
                }
            }
        }
        return SINGLETON;
    }
}

看吧什么问题也没有
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值