Lazy singleton中的double check

来源:互联网 发布:flash网站源码 编辑:程序博客网 时间:2024/06/12 00:20

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

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

写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;    }}

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

0 0
原创粉丝点击