安卓设计模式(二)单例模式

单例模式是使用最广的设计模式,也是大家最为熟知的.

该系列其他文章:

单例模式的使用场景

  • 该类会占用较多的资源,如线程资源,IO操作,网络请求等
  • 该类的数据应该是全局的,共享的
  • 该类的实例生命周期应该是全局的,在appliction的整个声明周期可能都需要用到

单例模式的具体写法

  • 恶汉式单例

恶汉式由于类加载时就创建好了对象,不存在线程安全和效率问题,缺点是过早的创建对象,并且不能在初始化时传参

public class Singleton {
    private static final Singleton sSingleton = new Singleton();

        private Singleton() {
    }

    public static Singleton getInstance() {
        return sSingleton;
    }
}
  • Double Check Lock实现单例

这种是目前使用最广泛的单例,线程安全,并且效率不低,我一般使用这种

public class Singleton {
    private volatile static Singleton sSingleton=null;

    private Singleton() {
    }

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

注意到使用了volatile关键字修饰单例对象,这样可以保证sSingleton对象每次都是从主内存中读取,从而避免在创建对象时由于Java内存模型带来的不必要的问题.

  • 静态内部类单例

这种也是比较好的单例,线程安全,保证唯一,延迟实例化统统都具有.

使用到java内部类的加载时机,只有在内部类的静态成员被调用时才会去加载静态内部类,所以同样是延迟加载

public class Singleton {

    private Singleton() {
    }

    public static Singleton getInstance() {
        return SingletonHolder.sSingleton;

    }

    private static class SingletonHolder {
        private static final Singleton sSingleton = new Singleton();
    }
} 
  • 枚举单例

利用到枚举的特性,在任何情况下,枚举默认就是单一实例,枚举的创建默认就是线程安全的.并且枚举跟普通类一样,可以拥有属性和方法.

public enum SingletonEnum {
    SINGLETON_ENUM;

    public void doSth() {
    
    }
}
  • 使用容器实现单例

这种单例管理方式在Android源码中有用到,在单例比较多的时候,采用容器来管理和获取单例是非常好的方式.在程序初始化时注入相应的单例,任何时候使用容器来获取单例.

public class SingletonManager {
    private static Map<String, Object> objectMap = new HashMap<String, Object>();

    private SingletonManager() {
    }

    public static void registerService(String key, Object instance) {//存入
        if (objectMap.containsKey(key)) {
            objectMap.put(key, instance);
        }
    }

    public static Object getService(String key) {//获取
        return objectMap.get(key);
    }
}

最后

以上五种是比较好的单例实现方式,均可保证线程安全,效率高,延迟实例化(恶汉式除外),我推荐使用DCL方式的单例

关于作者

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 180,678评论 25赞 708
  • 1 场景问题# 1.1 读取配置文件的内容## 考虑这样一个应用,读取配置文件的内容。 很多应用项目,都有与应用相...
    七寸知架构阅读 7,046评论 12赞 68
  • 我突然觉得和妈妈的关系到了一个历史的冰点,两个人的心越来越远,话越来越少,努力去说,也突然变得冷冰冰的,心里默念,...
    爱君如初阅读 363评论 0赞 0
  • 我没有很强大,也没有他说的好脾气,也会闹情绪,发牢骚,但在他们眼中这就是我,所有人都会评价的我,我不想这样,不想坐...
    zs97阅读 207评论 0赞 0
  • 柴静在采访一家药业工人因为抢修排污管死亡的事件,对药业老总用了质问和讽刺的话语,被领导批评,柴静说觉得对不起死去的...
    果冻骑单车阅读 1,271评论 2赞 0

友情链接更多精彩内容