应用最广的模式——单例模式

背景、

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

一、使用场景及思想

确保某个类中只有一个实例,且自行实例化并向系统提供这个实例
思想单例模式的几个关键点
1.构建函数不能对外开放,一般为Private。
2.通过一个静态方法返回实例化对象。
3.确保单列类只有一个,尤其是在多线程的情况下。
4.确保实例类对象在反序列化时不会重写构建。

二、饿汉单列模式

public class Instance {

    private static final Instance instance=new Instance();
    private Instance(){

    }
    public static Instance getInstance(){
        return instance;
    }

}

三、懒汉的加载模式

public class Instance1 {
    private static  Instance1 instance;
    private Instance1(){

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

}
可以发现getInstance方法中加了synchronized 关键字,也就是一个同步方法,这就是在上面说的在多线程情况下保证单列对象的手段,但是你会发现一个问题,及时instance被初始化每次调用的时候都会进行同步,这样会消耗不必要的资源,这个也是懒汉模式存在的问题大量地消耗资源,造成不必要的开销 。

四、Double Check Lock实现单列模式


public class Instance2 {
    private static  Instance2 instance;
    private Instance2(){

    }
    public static synchronized Instance2 getInstance(){

        if(instance==null){
            synchronized (Instance2.class) {
                    if (instance==null) {
                        instance=new Instance2();
                }
            }
        }
        return instance;
    }

}
双层判空第一层是为了避免不必要的同步,第二层是判断在null的情况下创建实例,这样的优点为 资源利用率高,第一次执行的时候单例对象才会被实例,效率高,如果不为null减少同步消耗资源直接返回这个单例。,缺点是第一次加载的时候反应比较慢,但是这个是模式是使用最多的单列方式,它能在需要的时候才加载实例化对象,并且在大多数情况下都可以保证唯一性。

五、使用容器实现单列模式

public class InstanceManager {

    private static Map<String, Object> objMap= new HashMap<String,Object>();
    private InstanceManager(){
    }

    private static void registerManager(String key,Object object){
        if (!objMap.containsKey(key)) {
            objMap.put(key,object);
        }
    }
    public static Object getService(String key){
        return objMap.get(key);
    }

}
在程序开始将多种类型注入管理类中,在使用时根据key获取对象对应类型的对象,这种方式使我们可以管理多种类型单列,并且可以通过统一的接口进行获取操作,减低了用户的使用成本,也对用户隐藏了具体实现,减低了耦合度

六、总结

不管以何种形式实现单例模式,它们的核心原理都是将构造方法私有化,并且通过静态方法获取一个唯一的实例,在这个获取的过程中必须保证线程安全,防止反序列化导致重新生成实例化对象等问题,我个人推荐使用双层锁判断
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值