【设计模式】单例模式的六种实现方式

记得几年前校招的时候,被某家公司要求手写单例模式,当时被问到时心里还在想“这么基础的问题还要问”,不过真的问到一些细节的时候,我答得还真不是太好。今天在看Glide源码时,突然想到可以总结出常用开源框架共通的东西,这也许才是研究源码的真正目的吧。
最近看的几个源码中都涉及到了单例模式,索性就在这里总结一下吧。

饿汉式

public class SingleTonEHan {
    //将构造函数私有化
    private SingleTonEHan() {
    }

    //创建私有实例对象
    private static final SingleTonEHan singleTonInstance = new SingleTonEHan();

    //对外提供方法,返回实例对象
    public static SingleTonEHan getInstance() {
        return singleTonInstance;
    }
}

优点:简单,线程安全
缺点:实例对象是static的,在声明的时候就实例化了,浪费资源。

懒汉式

public class SingleTonLanHan {

    //构造函数私有化
    private SingleTonLanHan() {

    }

    //声明私有实例对象
    private static SingleTonLanHan singleTonLanHan;

    //对外提供方法,返回并创建实例对象
    public static synchronized SingleTonLanHan getInstance() {
        if (null == singleTonLanHan) {
            singleTonLanHan = new SingleTonLanHan();
        }
        return singleTonLanHan;
    }
}

优点:用到的时候才会去实例化,在一定程度上节省了资源。
缺点:用synchronized关键字修饰,使得该方法是同步的,为了保证线程安全,但每次调用该方法的时候都会被同步,这样会消耗不必要的资源。所以这种模式一般不建议使用

Double Check Lock(DCL模式)

public class SingleTonDCL {

    //将构造函数私有化
    private SingleTonDCL() {

    }

    //声明私有化对象
    private static SingleTonDCL singleTonDCL;

    //对外提供,double check lock
    public static SingleTonDCL getInstance() {
        if (null == singleTonDCL) {
            synchronized (SingleTonDCL.class) {
                if (singleTonDCL == null) {
                    singleTonDCL = new SingleTonDCL();
                }
            }
        }
        return singleTonDCL;
    }
}

可以看到getInstance()方法对singleTonDCL进行两次判空,对懒汉式进行了优化,只有在第一次实例化的时候才会走第二个分支,才会同步,避免了每次都同步造成不必要的资源浪费。
优点:第一次getInstance的时候才会实例化,效率高。
缺点:暂无

静态内部类实现

public class SingTonInnerStatic {

    //将构造函数私有化
    private SingTonInnerStatic() {

    }

    //对外提供
    public static SingTonInnerStatic getInstance() {
        return SingleTonHolder.singleTonInnerStatic;
    }

    //静态内部类
    private static class SingleTonHolder {
        private static final SingTonInnerStatic singleTonInnerStatic = new SingTonInnerStatic();
    }
}

第一次调用getInstance的时候,虚拟机才会加载SingleTonHolder静态内部类
优点:线程安全,保证单例的唯一性,延迟了对象的实例化。推荐!
缺点:暂无

枚举

public enum SingleTonEnum {
    INSTANTCE
}

只是听说这种方式最屌,不过没具体研究过。待以后补充

容器实现单例

public class SingleTonManager {

    private SingleTonManager() {

    }

    private static Map<String, Object> objectMap = new HashMap<>();

    public static void registerService(String key, Object object) {
        if (!objectMap.containsKey(key)) {
            objectMap.put(key, object);
        }
    }

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

将多种单例注入到一个统一的管理类中,使用时根据key获取对应的对象,这种模式使得我们可以管理多种类型的单例,并且在使用的时候通过统一的接口获取。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值