天天看点

Android 单例模式几种写法及优缺点

总结一波单例设计模式的几种写法以及各自存在的优缺点。

1,饿汉式

顾名思义,实例对象早早的就创建出来了。这种方式在类加载的时候就完成了初始化,所以类加载过程比较缓慢,但是在使用过程中获取实例对象的速度比较快,也因为这种方式是基于类加载机制的,所以避免了多线程的同步问题。

public class SingleTon {

    private static SingleTon instance = new SingleTon();
    private SingleTon(){}

    public static  SingleTon getInstance(){
        return instance;
    }

}
           

优点:获取对象的速度快;避免了多线程的同步问题

缺点:类加载过程慢

2,懒汉式(线程不安全)

顾名思义,实例对象创建时间较晚。实例对象在用户第一次调用的时候初始化,虽然节约了资源,但是第一次加载时反应稍慢,而且在多线程的情况下不能正常使用。

public class SingleTon {

    private static SingleTon instance;

    private SingleTon() {}

    public static SingleTon getInstance() {
        if (instance == null) {
            instance = new SingleTon();
        }

        return instance;
    }
}
           

优点:节约资源

缺点:第一次加载时需要实例化,反应稍慢;多线程下不能正常工作

3,懒汉式(线程安全)

这种写法时线程安全的,在多线程情况下是可以正常工作的,但是每次获取实例对象的时候都需要进行同步,造成不必要的同步开销。在移动应用开发端用到同步的情况很少,所以不建议使用。

public class SingleTon {

    private static SingleTon instance;

    private SingleTon() {}

    public static synchronized SingleTon getInstance() {
        if (instance == null) {
            instance = new SingleTon();
        }

        return instance;
    }
}
           

优点:在多线程下可以安全的使用

缺点:造成不必要的同步开销

4,双重检查机制(DCL)

这种写法有两次判空。第一次判空是减少不必要的同步开销,也是对上面写法的改进;第二次判空是创建实例对象。注意这里使用了volatile关键字

public class SingleTon {

    private static volatile SingleTon instance;

    private SingleTon() {}

    public static SingleTon getInstance() {
        if (instance == null) {
            synchronized (SingleTon.class) {
                if (instance == null) {
                    instance = new SingleTon();
                }

            }
        }

        return instance;
    }
}
           

优点:资源利用率高,线程安全

缺点:第一次加载时反应稍慢,在高并发环境下有缺陷

5,静态内部类

这种单例模式在第一次类加载时并不会初始化,只有在第一次调用getInstance();时虚拟机加载SingletonHolder并初始化SingleTon实例,也是线程安全的,也是推荐使用的。

public class SingleTon {

    private SingleTon() {}
    
    public static SingleTon getInstance(){
       return SingletonHolder.instance;
    }

    private static class SingletonHolder{
        private static final SingleTon instance = new SingleTon();
    }

}
           

优点:线程安全,节约资源

缺点:第一次加载时反应稍慢

继续阅读