【设计模式】单例模式

1. 设计模式说明

单例模式是最常见的设计模式之一。它主要用来保证在应用中只有一个实例,可以对于线程池、数据库连接等重量级应用提高复用率,减少创建以及维持多实例时消耗的大量资源。常见的单例模式的实现方案有懒汉式、饿汉式、枚举、静态内部类四种方案。

2. 单例模式实现方案

2.1 饿汉式单例方案

饿汉式实现比较简单,就是在类加载时直接对创建静态实例并初始化,这样可以避免线程安全问题。也有人认为这是缺点,因为没有延迟加载,所以会在初始化时占用部分资源,导致初始化时间变长。但是如果资源初始化时间比较长的话,还是建议应用启动初始化,这样可以避免第一次访问时响应时间过长的问题。

样例代码如下:

java 复制代码
public class Singleton1 {
    private static Singleton1 instance = new Singleton1();
    private Singleton1() {
    }
    public static Singleton1 getInstance() {
        return instance;
    }
}

2.2 懒汉式单例方案

针对于饿汉式没有进行延迟初始化的缺点,懒汉式方案也就应运而生。但是对于懒汉式的方案需要注意线程安全问题,问了解决线程安全问题,可以使用双重检查锁的方式。

样例代码如下:

java 复制代码
public class Singleton {
  	// 防止指令重排并保证数据可见性
    private volatile Singleton instance ;
    private Singleton() {
    }
    public static Singleton getInstance() {
        // 只有在实例为空的情况下才会进行实例初始化
        if(instance == null){
           // 在多线程情况下,可能会存在同时多个实例为空的线程,所以需要使用同步锁
            synchronized (Singleton.class){
               // 对于进入同步锁的线程,第一个实例化后,后续的线程由于持有的instance依然为空,所以需要再次进行判断
                if(instance == null){
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

懒汉式使用双检锁是为了保证单例多线程读取的安全性,但同时由于代码容易遗漏部分内容,而且对于初学者来说不太容易理解,所以不建议使用。

2.3 静态内部类方案单例方案

静态内部类是一种类似于饿汉式的解决方案。它利用了Java的静态内部类的特点,那就是当Singleton默认不会被实例化,同时,当调用getInstance()方法时,InstanceHolder才会被创建,这样就满足了延迟加载的要求。同时由于是静态类,会由JVM保障实例的唯一性和线程安全性。

样例代码如下:

java 复制代码
public class Singleton {
    private Singleton() {
    }

    private static final class InstanceHolder {
        private static final Singleton instance = new Singleton();
    }

    public static Singleton getInstance() {
        return InstanceHolder.instance;
    }
}

2.4 枚举类单例方案

枚举方案也是利用了枚举类型线程安全且只会装载一次的特性。这也是 effective java 作者极力推荐的单例实现模式。

样例代码如下:

java 复制代码
public enum Singleton {
    Instance;
}

3. 推荐方案

  • 推荐使用枚举类实现方案。简单、便于理解,还有JVM对单例进行保证。
相关推荐
sarasuki34 分钟前
为什么 Agent 工具需要一个「协议」而不是「框架」:MCP 成为标准的底层逻辑
设计模式·agent·mcp
vivo互联网技术34 分钟前
知识不是文件,也不是向量 | KDC 系列 02
人工智能·设计模式·架构
Zane19946 天前
一个 new 就能创建对象,为什么还要拆出单例、工厂、建造者、原型四种模式?
设计模式
怕浪猫7 天前
一行命令复刻爆款视频,我把 Hypit 从安装跑到了出片
人工智能·设计模式·程序员
Zane19947 天前
函数式编程里的函数,其实不是你天天写的那个函数——三大编程范式的边界在哪
设计模式
Zane19948 天前
策略模式现在该不该上?一次讲清楚过度设计和设计不足怎么找平衡
设计模式
她说..8 天前
常见设计模式-模板方法模式
java·spring·设计模式·springboot
xiaofeiyang1508 天前
第六章 · 桥接 — 三支毛笔,画出九种颜色
设计模式
Shadow(⊙o⊙)9 天前
OTOL设计模式 One Thread One Loop
服务器·网络·设计模式
sarasuki9 天前
如何让LLM 能在半夜偷偷打开网易云呢?
人工智能·设计模式·agent