精讲Android设计模式-单例模式

推荐学习更多设计模式:

为什么要使用单例模式

单例的优点

1.只有一个实例,节省开销
2.全局使用方便,同时避免频繁创建和销毁

使用单例的注意点:
要避免造成 内存泄漏

常用的单例模式

单例不仅要满足线程安全,还要注意防止序列化产生新对象。如果单例实现了Serializable接口,就必须加入如下方法(枚举单例不用这么做,因为JVM能保障这点):

private Object readResolve()  throws ObjectStreamException{
    return INSTANCE;
}

饿汉式

饿汉式:就是在类初始化时就实例化,所以是线程安全的。
缺点是:
1.没有懒加载,在不需要的时候也会被实例化,造成内存浪费。
2.实例化方法对外部调用不友好,传参不方便

public class Singleton implements Serializable {
    private static final Singleton INSTANCE = new Singleton();
    // 私有化构造函数
    private Singleton(){}

    public static Singleton getInstance(){
        return INSTANCE;
    }

    /**
     * 如果实现了Serializable, 必须重写这个方法
     */
    private Object readResolve() throws ObjectStreamException {
        return INSTANCE;
    }
}

懒汉式

延迟加载(使用时加载),节省内存
双重判空,第一次判空防止重复加锁,第二次判空才实例化
防止DCL指令重拍序,加volatile关键字

public class Singleton {
    private volatile static Singleton INSTANCE; //声明成 volatile
    private Singleton (){}

    public static Singleton getSingleton() {
        if (INSTANCE == null) {                         
            synchronized (Singleton.class) {
                if (INSTANCE == null) {       
                    INSTANCE = new Singleton();
                }
            }
        }
        return INSTANCE;
    }

}

//如果实现了Serializable, 必须重写同上面饿汉式一样的readResolve方法

枚举式

由JVM保证线程安全
序列化和反射攻击已经被枚举解决

//enum枚举类
public enum Singleton { 
    INSTANCE;  
    public void yourMethod() {  

    }  
}

内部类实现单例

当Singleton被加载时,其内部类并不会被初始化,故可以确保当 Singleton类被载入JVM时,不会初始化单例类。只有 getInstance() 方法调用时,才会初始化 instance。同时,由于实例的建立是时在类加载时完成,故天生对多线程友好,getInstance() 方法也无需使用同步关键字。

public class Singleton { 
    /** 
     * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例没有绑定关系, 
     * 而且只有被调用到才会装载,从而实现了延迟加载 
     */ 
    private static class SingletonHolder{ 
        /** 
         * 静态初始化器,由JVM来保证线程安全 
         */ 
        private static final Singleton instance = new Singleton(); 
    } 
    /** 
     * 私有化构造方法 
     */ 
    private Singleton(){ 
    } 

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

发表评论

关闭菜单