Java创建型模式---单例模式

单例模式基础概念

单例模式是一种创建型设计模式,其核心思想是确保一个类仅有一个实例,并提供一个全局访问点来获取这个实例。在 Java 中实现单例模式主要有以下关键点:

  1. 私有构造函数 - 防止外部通过new关键字创建实例
  2. 静态实例变量 - 类内部持有唯一实例的引用
  3. 静态访问方法 - 提供全局访问该实例的入口

单例模式的几种实现方式

1. 饿汉式(线程安全)

饿汉式是最简单的实现方式,在类加载时就创建实例:

复制代码
public class EagerSingleton {
    // 类加载时就初始化实例
    private static final EagerSingleton instance = new EagerSingleton();
    
    // 私有构造函数
    private EagerSingleton() {}
    
    // 静态访问方法
    public static EagerSingleton getInstance() {
        return instance;
    }
}

优点 :实现简单,线程安全
缺点:类加载时就创建实例,可能造成资源浪费

2. 懒汉式(非线程安全)

懒汉式在首次调用时才创建实例,但存在线程安全问题:

复制代码
public class LazySingleton {
    private static LazySingleton instance;
    
    private LazySingleton() {}
    
    // 非线程安全的获取实例方法
    public static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

优点 :延迟加载,避免资源浪费
缺点:多线程环境下可能创建多个实例

3. 懒汉式(线程安全,同步方法)

为了解决线程安全问题,可以对获取实例的方法进行同步:

复制代码
public class LazySingletonSynchronized {
    private static LazySingletonSynchronized instance;
    
    private LazySingletonSynchronized() {}
    
    // 同步方法,保证线程安全
    public static synchronized LazySingletonSynchronized getInstance() {
        if (instance == null) {
            instance = new LazySingletonSynchronized();
        }
        return instance;
    }
}

优点 :线程安全,延迟加载
缺点:同步方法开销大,影响性能

4. 双重检查锁定(Double-Checked Locking)

结合懒加载和性能优化的双重检查锁定实现:

复制代码
public class DoubleCheckedLockingSingleton {
    // 使用volatile关键字保证可见性和禁止指令重排序
    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 关键字的作用

5. 静态内部类(推荐)

利用 Java 静态内部类的特性实现高效、线程安全的单例:

复制代码
public class StaticInnerClassSingleton {
    private StaticInnerClassSingleton() {}
    
    // 静态内部类,持有外部类的实例
    private static class SingletonHolder {
        private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
    }
    
    public static StaticInnerClassSingleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

优点 :线程安全,延迟加载,实现简单
缺点:无法传递参数

6. 枚举(最佳实践)

使用枚举实现单例是最简洁、最安全的方式:

复制代码
public enum EnumSingleton {
    INSTANCE;
    
    // 可以添加实例方法
    public void doSomething() {
        System.out.println("Singleton method called");
    }
}

优点

  • 线程安全
  • 防止反序列化重新创建新的对象
  • 防止反射攻击
  • 实现简单

缺点:无法实现延迟加载

单例模式的应用场景

单例模式在以下场景中经常使用:

  1. 资源管理器 - 如数据库连接池、文件系统
  2. 配置信息类 - 全局配置信息的读取和管理
  3. 日志记录器 - 统一的日志输出管理
  4. GUI 组件 - 如窗口管理器、对话框等

注意事项

  1. 序列化问题:如果单例类实现了 Serializable 接口,需要添加 readResolve () 方法防止反序列化创建新实例
  2. 反射攻击:私有构造函数可以被反射破坏,枚举实现可以避免此问题
  3. 多线程环境:必须考虑线程安全问题,推荐使用静态内部类或枚举实现

单例模式虽然简单,但在实际应用中需要根据具体场景选择合适的实现方式,同时注意处理好各种边界情况,确保单例的唯一性和安全性。

相关推荐
mldong6 小时前
一个 App,十三套后端:手机审批端 uni-jeeflow-app 开源了
java·架构
tqs_123457 小时前
MySQL RR隔离级别死锁|Gap间隙锁、临键锁,订单并发范围查询死锁根因方案
java
逆境不可逃7 小时前
Pi Agent 学习笔记:多个工具怎样并行执行
java
Flynt8 小时前
Java 27 升级实测:默认值动得比新特性多,有个老参数会让 JVM 直接起不来
java·jvm·后端
Bs_MoneyMagnet8 小时前
基于springboot+vue的个人健康管理系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·vue3·springboot3·计算机毕业设计
星云API技术支持8 小时前
企业微信二次开发:群权限设置、成员管理与群资料维护的接口组合实践
java·前端·企业微信
niucloud-admin9 小时前
JAVA V6 多商户商城 开发文档——job 计划任务开发
java·python·github
海宇AI10 小时前
零信任架构实战:基于海宇柠檬查出险-登记证构建自动化车抵贷核保网关
java·人工智能·架构·自动化
xiangyun6110 小时前
【408数据结构 08】队列:循环队列判空判满,408年年考,一次讲清
c语言·开发语言·数据结构·c++·算法
xiangyun6110 小时前
【408数据结构 06】双链表、循环链表、静态链表
c语言·开发语言·数据结构·c++·算法