设计模式-单例模式

单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类仅有一个实例,并提供一个全局访问点来访问这个实例。单例模式在软件开发中被广泛应用,特别是在那些需要严格控制实例数量,确保资源唯一性或共享资源的场景中。

1. 单例模式的特点

  • 唯一性:在整个应用程序的生命周期内,一个特定的单例类只能有一个实例。这保证了在不同部分的代码中访问的是同一个对象,避免了因创建多个实例可能导致的资源浪费或数据不一致问题。
  • 全局访问点:单例模式提供了一个全局访问点,通常是一个静态方法,使得应用程序的任何部分都可以方便地获取到这个唯一的实例。

2. 单例模式的实现方式

常见的单例模式实现方式有以下几种:

  • 饿汉式单例:在类加载时就立即创建实例,所以它是线程安全的。
java 复制代码
public class EagerSingleton {
    // 在类加载时就创建实例
    private static final EagerSingleton instance = new EagerSingleton();

    // 私有构造函数,防止外部实例化
    private EagerSingleton() {}

    // 提供全局访问点
    public static EagerSingleton getInstance() {
        return instance;
    }
}
  • 懒汉式单例(线程不安全) :在第一次调用 getInstance 方法时才创建实例。但这种方式在多线程环境下是不安全的,可能会创建多个实例。
java 复制代码
public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {}

    // 线程不安全的获取实例方法
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}
  • 懒汉式单例(线程安全) :通过在 getInstance 方法上加 synchronized 关键字来确保线程安全,但这种方式会影响性能,因为每次调用该方法都需要进行同步操作。
java 复制代码
public class ThreadSafeLazySingleton {
    private static ThreadSafeLazySingleton instance;

    private ThreadSafeLazySingleton() {}

    // 线程安全的获取实例方法
    public static synchronized ThreadSafeLazySingleton getInstance() {
        if (instance == null) {
            instance = new ThreadSafeLazySingleton();
        }
        return instance;
    }
}
  • 双重检查锁(DCL)单例 :这是一种优化的懒汉式单例实现,既保证了线程安全,又提高了性能。它通过两次检查 instance 是否为 null,减少了不必要的同步操作。
java 复制代码
public class DoubleCheckedLockingSingleton {
    private static volatile DoubleCheckedLockingSingleton instance;

    private DoubleCheckedLockingSingleton() {}

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

这里使用 volatile 关键字是为了确保 instance 变量的可见性,防止指令重排导致的问题。

  • 静态内部类单例 :利用了类加载机制来保证线程安全,并且只有在调用 getInstance 方法时才会加载内部类并创建实例。
java 复制代码
public class StaticInnerClassSingleton {
    private StaticInnerClassSingleton() {}

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

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

3. 单例模式的适用场景

  • 资源管理:例如数据库连接池、线程池等,这些资源创建成本较高,使用单例模式可以确保在整个应用程序中只创建一个实例,避免资源的重复创建和浪费。
  • 全局配置:应用程序的全局配置信息,如系统参数、配置文件的读取实例等,使用单例模式可以保证在不同模块中获取到的配置信息是一致的。
  • 日志记录:日志记录器通常设计为单例,确保在整个应用程序中使用同一个日志记录实例,方便统一管理和记录日志信息。

4. 单例模式的优缺点

  • 优点
    • 节省资源:避免了频繁创建和销毁对象带来的资源开销,特别是对于创建成本较高的对象。
    • 数据一致性:由于只有一个实例,不同部分的代码对其进行操作时,数据是一致的,便于共享和管理数据。
  • 缺点
    • 全局状态:单例模式可能导致全局状态的存在,使得代码的可测试性变差。在单元测试中,可能需要特殊的处理来模拟单例的行为。
    • 并发问题:如果实现不当,在多线程环境下可能会出现线程安全问题,如创建多个实例等。

单例模式是一种简单而强大的设计模式,在适当的场景下使用可以提高程序的性能和资源管理效率,但需要注意其线程安全性和对代码可测试性的影响。

相关推荐
就叫_这个吧几秒前
HTML或JSP页面链接CSS,link标签没问题,但不显示样式问题解决
java·前端·css·html·intellij-idea·jsp
阿坤带你走近大数据5 分钟前
分别介绍下java主流的开发框架、设计模式与对应编程语言的高级特性
java·开发语言·设计模式
番茄去哪了13 分钟前
一篇文章讲懂SDN
java·spring
AC赳赳老秦18 分钟前
OpenClaw + 华为云自动化:批量管理云资源、生成月度云账单分析与成本优化报告
java·开发语言·javascript·人工智能·python·mysql·openclaw
我是一颗柠檬24 分钟前
【Java项目技术亮点】读写分离+主从延迟处理:MySQL高并发下的性能优化方案
java·分布式·mysql·性能优化
qq_25183645725 分钟前
基于java Web 哈尔滨文化活动网站毕业论文
java·开发语言·前端
Java知识技术分享27 分钟前
安装sourcetree
java·git·源代码管理
geovindu34 分钟前
go: Coroutines Pattern
开发语言·后端·设计模式·golang·协程模式
Stick_ZYZ35 分钟前
A2A:让 Agent 从单兵作战走向团队协作
java·开发语言·网络·人工智能·python·ai
天才少年曾牛36 分钟前
Android新增服务添加selinux权限
android·java·frameworks