软件设计之单例模式(四)

本篇主要介绍几种常用的写法,还是以Java语言为例,其中会涉及到Java语言的特性,如果用其他语言来写单例模式,主要还是抓住单例的全局唯一性原则去考虑即可。

如果想看往期单例模式的,可以从这些链接进入:

软件设计之单例模式(一)

软件设计之单例模式(二)

软件设计之单例模式(三)

关于单例模式,其实网上也早有流传一种叫法,分别是懒汉模式和饿汉模式,

所谓懒汉模式即懒加载,也就是等到用的时候再去创建单例对象,而饿汉模式即立即创建单例对象,下面来介绍几种常用的几种单例写法:包括2种懒汉模式 + 2种饿汉模式:

第一种:饿汉模式​​​​​​

public class Singleton {
    private static Singleton singleton = new Singleton();
    private Singleton(){

    }
    public Singleton getInstance(){
        return singleton;
    }
}

在Singleton类初始化的时候就创建了单例对象singleton,这也是饿汉模式的命名的原因;这种模式在软件设计之单例模式(一)的时候我们也分析过。

第二种:懒汉模式


public class Singleton {
    private static Singleton singleton;

    private Singleton(){
    }

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

这种模式就是在用的时候,才创建单例对象,关于两次的校验if (singleton == null)和synchronized 主要是起到了多线程安全和优化性能的作用,在软件设计之单例模式(二)软件设计之单例模式(三)中也仔细分析过。

第三种:懒汉模式 ,运用java内部类的写法

这种写法其实跟语言特性有关,内部类也是java中一种特性写法,不一定每种语言都有,所以当用其他语言来写的时候,要注意语言特性问题。


public class Singleton {
    static {
        System.out.println("外部类初始化....");
    }
    private Singleton() {
    }
    private static class SingletonHolder {
        static {
            System.out.println("内部类初始化");
        }
        private static final Singleton INSTANCE = new Singleton();
    }
    public static final Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
    public static void test(){
        System.out.println("test....");
    }
}

这种写法,就是在Singleton类中加了一个SingletonHolder类,这就是内部类,所谓的内部类,就是一个大类中还有一个小类,只有当调用到getInstance方法的时候,才会去加载SingletonHolder这个类(Java类加载原理,后面会专门有篇章介绍类加载),这样就能满足调用时再创建对象的条件了,另外由于类加载是线程安全的,所以这里也不会有多线程竞争条件存在,也符合了全局唯一性原则。

第四种:饿汉模式 ,运用java 枚举类enum的写法

枚举enum也是java语言的一个特性,跟上面的👆内部类一样,具体选择语言的时候,还是要根据语言特性去选择。


public enum EnumSingleton {
    INSTANCE;
}

这种方式也是单例模式的最简写法,也是《Effective Java》作者Josh Bloch推荐的写法,既能保证多线程安全,也能保证单例对象全局唯一性。

其实写到这里似乎意犹未尽,时间不多,今天就先列举单例模式常用的4种写法,下一篇会继续介绍一些遗留的问题,比如:

  1. 类加载机制为什么能保证线程安全?

  2. 枚举enum的单例是什么原理?为何《Effective Java》作者推荐这种写法? 

  3. ......

等等问题,会在下一篇继续讨论,如果有其他没有涵盖到的问题或者疑问,也欢迎读者一起提问讨论。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值