大家好,欢迎来到程序视点!
前言
在前面三期里,我们详细讲解了工厂模式下的三种分类:
其中,简单工厂模式不是我们23中设计模式之气,其他两个设计模式都属于创建型模式
的设计方式。
今天,我们要接着讲另一种创建型模式:单例模式
。
单例模式简介
单例模式是比较常见的一种设计模式,目的是保证一个类只能有一个实例。
这个实例就是其唯一的对象,可以直接访问,不需要在其他地方实例化该类的对象。
注意三点:
- 单例类只能有一个实例。
- 单例类必须自己创建自己的唯一实例。
- 单例类必须给所有其他对象提供这一实例。
关键代码有两点:
- 私有构造函数
- 对外暴露获取唯一实例的方法
示例
关于单例模式的创建,我们不得不了解其中的两种方式:懒汉式和饿汉式。
首先来看懒汉式
。之所以取这个名称,是因为类的实例并不是一开始就创建好的,而是“懒”到第一次获取的时候才创建。
public class Singleton {
//构造函数私有化
private Singleton(){}
//“懒”就懒在这里。可以对比后面的饿汉式。
private static Singleton singleton = null;
//暴露获取唯一实例的方法
public static Singleton getSingleton(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
这种方式是最基本的实现方式。但这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized
,所以严格意义上它并不算单例模式。
由于线程安全并不是我们要讲的主要内容,这里就不展开分析了
ps:在我们后面讲多线的时候,会详细分析。敬请期待!
再来看看饿汉式
。这和上面的懒汉式不同:它是直接一开始就创建好一个实例化的对象。不会管这个实例会不会立即被使用。
class Singleton2 {
//私有构造函数
private Singleton2(){};
// 太“饿”了,得先new个实例先垫下
private static Singleton2 singleton2= new Singleton2();
//暴露获取唯一实例的方法
public static Singleton2 getSingleton2(){
return singleton2;
}
}
这种方式比较常用。同时不用去考虑加锁的问题,执行效率会高些!但有个缺点:类加载时就初始化,浪费内存。
🆗,我们已经实现了单例模式的创建了。
现在我们需要思考一个问题:懒汉式和饿汉式都有各自的缺点,那有没有一种单例模式能弥补这些缺点呢?
答案是:有的!我们常说的Double-Locked-Checking
就是其中之一.
class Singleton3{
//私有构造函数
private Singleton3(){}
private static Singleton3 singleton3 = null;
public static Singleton3 getSingleton3(){
//先检查实例是否存在,如果不存在才进入下面的同步块
if(singleton3 == null){
//同步块,线程安全的创建实例
synchronized (Singleton3.class) {
//再次检查实例是否存在,如果不存在才真正的创建实例
if(singleton3 == null){
singleton3 = new Singleton3();
}
}
}
return singleton3;
}
}
这种方式采用双锁机制,安全且在多线程情况下能保持高性能。
但这种方式还存在一个问题。我在这里先卖个关子。细心的小伙伴如果发现了,可以给我留言哦!ps:这里可能出现的问题我们在后期中会详细分析
DCL方式主要是在实例域需要延时初始化使用。我们还有一种在静态域使用的方式。
class Singleton4{
private Singleton4(){};
private static class Singleton4Holder{
//静态初始化器,由JVM来保证线程安全
private static Singleton4 singleton4 = new Singleton4();
}
public static Singleton4 getSingleton4(){
return Singleton4Holder.singleton4;
}
}
采用静态(类级)内部类
的方式,将实例放在静态成员内部类中。这样内部类的实例与外部类的实例没有绑定关系,而且只有被调用到时才会装载,从而实现了延迟加载。
好了!我们今天的单例模式就介绍到这里。想要了解更多设计模式的信息,敬请关注微信公众号:程序视点。我们下期再会!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· 【.NET】调用本地 Deepseek 模型
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库