单例模式

单例模式介绍

单例模式是应用最广的模式之一,也可能是很多初级工程师唯一会使用的设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个全局对象,这样有利于我们协调系统整体的行为。如在一个应用中,应该只有一个ImageLoader实例,这个ImageLoader中又含有线程池、缓存系统、网络请求等,很消耗资源,因此,没有理由让它构造多个实例。这种不能自由构造对象的情况,就是单例模式的使用场景。

单例模式的定义

确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

单例模式的使用场景

确保某个类有且只有一个对象的场景,避免产生多个对象消耗过多的资源,或者某个类型的对象只应该有且只有一个。例如,创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源,这时就要考虑使用单例模式。

单例模式的几种实现方式:

  • Double Check LOCK(DCL)双重检查锁定(不推荐)

DCL优点:资源利用率高,第一次执行getInstance时对象才会被实例化,效率高。缺点:第一次加载时反应慢,也由于java内存模型原因偶尔会失败。在高并发环境下也有一定缺陷,虽然发生概率很小。DCL模式是使用最多的单例实现方式,它能够在需要时实例化单例对象,并且在绝大多数情况下保证单例对象的唯一性,除非你的代码在并发场景比较复杂或者低于1.6版本下使用,否则,这种方式一般能满足需求

public class Singleton {
    private static Singleton mInstance = null;
    private Singleton(){}
    public static Singleton getsInstance(){
        if(mInstance==null){
            synchronized (Singleton.class){
                if(mInstance == null){
                    mInstance = new Singleton();
                }
            }
        }
        return mInstance;
    }
}
  • 静态内部类单例模式(推荐)
    DCL 虽然在一定程度上解决了资源消耗、多余的同步、线程安全等问题,但是它还是在某些情况下出现失效的问题。这个问题被称为双重检查锁失效,在《java并发编程实践》一书中 最后谈到这个问题,并指出这种“优化”是丑陋的,不赞成使用。而建议使用如下代码代替:
public class Singleton {
    private Singleton(){}
    public static Singleton getsInstance(){
        return SingleTonHolder.mInstance;
    }

    /**
     * 静态内部类
     */
    private static class SingleTonHolder{
        private static final Singleton mInstance = new Singleton();
    }
}
  • 枚举单例
public class Configurator {

    public static Configurator getInstance(){
        return Holder.INSTANCE;
    }

    //静态内部类的单例初始化
    private static class Holder{
        private static final Configurator INSTANCE = new Configurator();
    }
}

  • 使用容器实现单例模式(略)

参考《Android 源码设计模式》

你可能感兴趣的:(设计模式,单例,设计模式)