【设计模式系列】单例模式(二十)

一、什么是单例模式

单例模式(Singleton Pattern)是一种常用的软件设计模式,属于创建型模式。它的目的是确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。

单例模式的主要特点包括:

  1. 唯一性:单例类在整个应用程序的生命周期内只创建一个实例。
  2. 全局访问点:提供了一个全局的访问点,确保所有访问该类的地方都访问的是同一个实例。
  3. 延迟初始化:单例实例通常在第一次被使用时创建(懒汉式),也可以在程序启动时立即创建(饿汉式)。

二、单例模式的典型实现案例

2.1 懒汉式(线程不安全)

  • 这种方式下,实例在第一次被使用时才创建。这种方式简单,但在多线程环境下可能会出现多个实例的问题。
java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

2.2 饿汉式(线程安全)

  • 在类加载时就立即初始化单例,这种方式避免了多线程的同步问题,但可能导致资源的浪费,因为不管是否使用,单例都会被创建。
java 复制代码
public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {}

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

2.3 双重校验锁(Double-Checked Locking,线程安全,推荐方式)

  • 这种方式在获取实例时先检查实例是否已经创建,如果没有创建才进入同步块中创建实例。这种方式既保证了线程安全,又避免了每次访问都进行同步的开销。
java 复制代码
public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

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

2.4 静态内部类(线程安全)

  • 这种方式利用了类加载机制来保证初始化实例时只有一个线程,同时也实现了延迟加载。
java 复制代码
public class Singleton {
    private Singleton() {}

    private static class SingletonHolder {
        private static final Singleton INSTANCE = new Singleton();
    }

    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

单例模式适用于需要全局只有一个实例的场景,如配置管理器、线程池、缓存等。然而,过度使用单例可能会导致代码的耦合度高,难以测试和维护。因此,在设计时需要根据实际需求谨慎使用单例模式。

相关推荐
野生技术架构师3 分钟前
Spring Boot 实现数据脱敏:自定义注解 + Jackson 序列化器
java·spring boot·后端
AI人工智能+电脑小能手10 分钟前
大白话说Java设计模式-28-模板方法模式(业务实战篇)
java·设计模式·模板方法模式·spring源码·订单系统·代码复用
奥莱维13 分钟前
KNX酒店方案_KNX专用线与高端酒店技术逻辑
java·服务器·前端·数据库
工业一体机老司机22 分钟前
Linux工业一体机自启动服务配置:systemd服务单元编写与开机优化实战
java·linux·服务器
weixin_538601971 小时前
智能体测开Day56
java
杨丰玮4181 小时前
从零手写Java飞机躲障碍游戏|Swing绘图、鼠标跟随、计时器碰撞检测实战(五)
java·python·游戏·游戏引擎·图形渲染·动画·贴图
莫得感情 o1 小时前
踩坑 - 压测三轮后 502:一个默认 10 的连接池如何拖垮整个服务
java
Escalating_xu1 小时前
【Linux线程】线程控制全解析:终止、join/detach、cancel、线程栈与 NPTL(下篇)
java·linux·运维
2602_959960922 小时前
电商大厂Java面试实录:Spring Boot/JVM/Redis/Kafka/微服务/安全/测试全解析
java·jvm·spring boot·redis·面试题
吃饱了得干活2 小时前
限界上下文之后:微服务怎么拆、上下文怎么聊?
java·后端·架构