设计模式(四):单例模式

设计模式(四):单例模式

  • [1. 单例模式的介绍](#1. 单例模式的介绍)
  • [2. 单例模式的类图](#2. 单例模式的类图)
  • [3. 单例模式的实现](#3. 单例模式的实现)
    • [3.1 懒汉式(线程不安全)](#3.1 懒汉式(线程不安全))
    • [3.2 懒汉式(线程安全)](#3.2 懒汉式(线程安全))
    • [3.3 饿汉式](#3.3 饿汉式)
    • [3.4 静态内部类](#3.4 静态内部类)
    • [3.5 枚举](#3.5 枚举)

1. 单例模式的介绍

单例模式(Singleton Pattern)属于创建型模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。

优点:

  1. 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例
  2. 避免对资源的多重占用。

缺点:

  1. 没有接口,不能继承。
  2. 与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外部怎么样来实例化。

2. 单例模式的类图

3. 单例模式的实现

3.1 懒汉式(线程不安全)

这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。

java 复制代码
package blog;

public class SingleObject {
    private static SingleObject instance;

    private SingleObject() {}

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

        return instance;
    }
}

3.2 懒汉式(线程安全)

这种方式采用双锁机制,安全且在多线程情况下能保持高性能。

java 复制代码
package blog;

public class SingleObject {
    private volatile static SingleObject instance;

    private SingleObject() {}

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

3.3 饿汉式

这种方式比较常用,没有加锁,执行效率会提高。但在类加载时就初始化,浪费内存。

java 复制代码
package blog;

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

    private SingleObject() {}

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

3.4 静态内部类

这种方式是 SingleObject 类被装载了,INSTANCE 不会被初始化。因为SingleObjectHolder 类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载SingleObjectHolder类,从而实例化INSTANCE。即实现了延迟加载,也保证线程安全。

java 复制代码
package blog;

public class SingleObject {
    private static class SingleObjectHolder {
        private static final SingleObject INSTANCE = new SingleObject();
    }

    private SingleObject() {}

    public static SingleObject getInstance() {
        return SingleObjectHolder.INSTANCE;
    }
}

3.5 枚举

这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它不仅能避免多线程安全问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。

java 复制代码
package blog;

public class SingleObject {
    enum SingletonEnum {
        INSTANCE;
        
        private final SingleObject unique;
        
        SingletonEnum() {
            unique = new SingleObject();
        }

        public SingleObject getInstnce(){
            return unique;
        }
    }

    private SingleObject() {}

    public static SingleObject getInstance() {
        return SingletonEnum.INSTANCE.getInstnce();
    }
}
相关推荐
小师兄吃牛肉8 分钟前
SQL 编辑器异常排查:基于 KStudio 的一次实战记录
java·sql·编辑器
m0_5873830010 分钟前
无人自助拼豆系统开发实战指南 核心功能架构搭建与落地经验分享
java·经验分享·spring·小程序·架构·需求分析
Wang's Blog14 分钟前
Java 项目实战: 交友项目 - Dubbo 超时与重试
java·dubbo·交友
BD_Marathon17 分钟前
ChatPromptTemplate的高级特性
android·java·javascript
要开心吖ZSH24 分钟前
定时任务是用外部调度(xxl-job)还是本地化( @Scheduled)更香?以号源刷新任务为例?
java·xxl-job·定时任务·scheduled
nagualky12325 分钟前
GPT-4 系列退役在即:一套可回滚的模型迁移验收法
java·开发语言·ai·架构
今天的砖头有点烫手啊26 分钟前
Java 8 Stream 原理拆解:惰性求值与并行流陷阱
java·jvm
starzy199033 分钟前
Flink 任务调度 Graph 源码深度剖析:从 StreamGraph 到 ExecutionGraph 的三层演进
java·大数据·flink
Eyfcom35 分钟前
〖实战〗快运系统 Oracle 性能优化:从“能用”到“扛住双11”的 Java + Spring Boot 实战
java·oracle·性能优化·快递管理系统
geovindu40 分钟前
rust: Chain of Responsibility Pattern
开发语言·后端·设计模式·rust·责任链模式·行为模式