单例设计模式的五种写法

来源:互联网 发布:淘宝二手闲鱼网站 编辑:程序博客网 时间:2024/05/18 01:16

欢迎加入QQ群探讨Android开发技术—>QQ群【软件开发-Android】:314896948


前段时间一直在使用单例模式,发现了一些问题,于是在网上查了些资料,研究了一下,总结下单例设计模式的几种写法以及各自的特点。

  • 写法一:

    public class SingleInstance {    private volatile static SingleInstance instance;    private SingleInstance() {}    public static SingleInstance getInstance() {        if (instance == null) {            instance = new SingleInstance();        }        return instance;    }    // do other work}

    特点:线程不安全,适用于单线程使用。

  • 写法二:

    public class SingleInstance {    private volatile static SingleInstance instance;    private SingleInstance() {}    public synchronized static SingleInstance getInstance() {        if (instance == null) {            instance = new SingleInstance();        }        return instance;    }    // do other work}

    特点:相比第一种在getInstance()方法上添加了synchronized,确保了线程安全,可适用于多线程,但是性能下降了,在每次调用方法的时候都需要同步,降低效率。

  • 写法三:

    public class SingleInstance {    private volatile static SingleInstance instance;    private SingleInstance() {}    public static SingleInstance getInstance() {        if (instance == null) {            synchronized (SingleInstance.class) {                if (instance == null) {                    instance = new SingleInstance();                }            }        }        return instance;    }    // do other work}

    特点:使用双重校验同步代码块。线程安全,适合很多场景使用,但是也存在一个缺陷就是instance = new SingleInstance();这句可能引起instance为null,因为在变量赋值时new 的对象可能存在为创建完成。

  • 写法四:

    public class SingleInstance {    private volatile static SingleInstance INSTANCE = new SingleInstance();    private SingleInstance() {}    public static SingleInstance getInstance() {        return SingleInstance.INSTANCE;    }    // do other work}

    特点:使用静态内部类的方式。这种方式利用classloder的机制来保证初始化instance时只有一个线程,因此是线程安全的,同时只会第一次创建实例对象。

  • 写法五:

    public enum SingleInstance {    INSTANCE;    private SingleInstance() {}    // do other work}

    特点:使用枚举的方式,线程安全,性能也比较搞,代码也比较简洁,是单例最佳的一种写法,但是也存在一个局限性:在获取实例的时候如果需要传入参数就不便了,如果仅仅传入上下文则可以拿取Application中上下文,如果是数据参数则无法传入。

  • 实际场景中个人偏好于使用后两种写法,感觉使用枚举更佳,毕竟一般入参不会有什么数据,需要的话可以使用方法获取。

0 0