创建篇-单例模式


前言

单例模式(Singleton)是一种非常简单且容易理解的设计模式。顾名思义,单例即单一的实例,确切地讲就是指在某个系统中只存在一个实例,同时提供集中、统一的访问接口,以使系统行为保持协调一致。singleton一词在逻辑学中指“有且仅有一个元素的集合”,这非常恰当地概括了单例的概念,也就是“一个类仅有一个实例”。


提示:以下是本篇文章正文内容,下面案例可供参考

一、饿汉式

这就是“饿汉模式”(eager initialization),即在初始阶段就主动进行实例化,并时刻保持一种渴求的状态,无论此单例是否有人使用。

public class Singleton2 {
    private static final Singleton2 instance = new Singleton2();

    private Singleton2() {
    }

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

要点:

  1. 构造方法私有,这样实例化工作完全归属于内部事务,任何外部类都无权干预。
  2. 实例私有,确保实例的私有性、不可见性和不可访问性。
  3. "static"关键字保证实例在类加载的时候就初始化,不会被GC回收。
  4. "final"关键字保证实例是个常量,一旦赋值后不能被修改。

二、懒汉式

1.有缺陷的懒汉式

如代码所示,只有在某线程第一次调用getInstance()方法时才会运行对该类进行实例化的逻辑代码,之后再请求就直接返回此实例了。这样的好处是如无请求就不实例化,节省了内存空间。这样的程序逻辑看似没问题,但其实在多线程模式下是有缺陷的。试想如果是并发请求的话,程序判空逻辑就会同时成立,这样就会多次实例化,并且对instance进行多次赋值(覆盖)操作,这违背了单例的理念。

public class Singleton1 {
    private static Singleton1 instance;

    private Singleton1() {
    }

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

2.改进后的懒汉式

大家注意到没有,我们一共用了2个嵌套的判空逻辑,这就是懒加载模式的“双检锁”:外层放宽入口,保证线程并发的高效性;内层加锁同步,保证实例化的单次运行。如此里应外合,不仅达到了单例模式的效果,还完美地保证了构建过程的运行效率,一举两得。

public class Singleton3 {
    private static Singleton3 instance;

    private Singleton3() {
    }

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

要点:

  1. “synchronized”关键字,不添加在方法上而是锁同步代码块,减小锁的粒度,提高效率。

总结

提示:这里对文章进行总结:

  1. 相比“懒汉模式”,其实在大多数情况下我们通常会更多地使用“饿汉模式”,原因在于这个单例迟早是要被实例化占用内存的,延迟懒加载的意义并不大,加锁解锁反而是一种资源浪费,同步更是会降低CPU的利用率,使用不当的话反而会带来不必要的风险。越简单的包容性越强,而越复杂的反而越容易出错、
  2. 除了“饿汉”与“懒汉”这2种单例模式,其实还有其他的实现方式。但万变不离其宗,它们统统都是由这2种模式发展、衍生而来的。我们都知道Spring框架中的IoC容器很好地帮我们托管了业务对象,如此我们就不必再亲自动手去实例化这些对象了,而在默认情况下我们使用的正是框架提供的“单例模式”。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhixuChen200

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值