23种设计模式-创建型模式之单例模式(Java版本)

Java 单例模式(Singleton Pattern)详解

🌟 什么是单例模式?

单例模式确保一个类只有一个实例,并提供一个全局访问点来访问它。


🧠 使用场景

  • 配置管理类(如读取配置文件)
  • 日志工具类(如 Log4j 的 Logger)
  • 数据库连接池
  • 缓存管理
  • 线程池

✅ 实现方式(Java)

方式一:饿汉式(类加载时就实例化)

java 复制代码
public class Singleton {
    private static final Singleton instance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return instance;
    }
}
  • 优点:简单、线程安全
  • 缺点:类加载时就创建实例,可能浪费资源

方式二:懒汉式(线程不安全)

java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 缺点:多线程环境会创建多个实例

方式三:懒汉式 + synchronized(线程安全)

java 复制代码
public class Singleton {
    private static Singleton instance;

    private Singleton() {}

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
  • 缺点:加锁影响性能

方式四:双重检查锁(DCL)

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;
    }
}
  • 优点:懒加载 + 线程安全 + 性能较好
  • volatile 防止指令重排

方式五:静态内部类

java 复制代码
public class Singleton {

    private Singleton() {}

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

    public static Singleton getInstance() {
        return Holder.instance;
    }
}
  • 优点:利用 JVM 机制,线程安全 + 懒加载 + 高性能

方式六:枚举实现(最推荐)

java 复制代码
public enum Singleton {
    INSTANCE;

    public void doSomething() {
        System.out.println("Doing something...");
    }
}
  • 优点:防反射、防反序列化、天然线程安全
  • 缺点:不能延迟加载

🔐 防止反射与反序列化破坏单例

防反射

java 复制代码
private Singleton() {
    if (instance != null) {
        throw new RuntimeException("反射破坏单例!");
    }
}

防反序列化

java 复制代码
private Object readResolve() {
    return instance;
}

📌 各方式对比

实现方式 是否懒加载 是否线程安全 推荐度
饿汉式 ★★
懒汉式
synchronized ★★
DCL ★★★★
静态内部类 ★★★★★
枚举 ★★★★★(最安全)
相关推荐
DuelCode33 分钟前
Windows VMWare Centos Docker部署Springboot 应用实现文件上传返回文件http链接
java·spring boot·mysql·nginx·docker·centos·mybatis
浪裡遊33 分钟前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
优创学社238 分钟前
基于springboot的社区生鲜团购系统
java·spring boot·后端
幽络源小助理1 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
猴哥源码1 小时前
基于Java+springboot 的车险理赔信息管理系统
java·spring boot
lzb_kkk1 小时前
【C++】C++四种类型转换操作符详解
开发语言·c++·windows·1024程序员节
YuTaoShao1 小时前
【LeetCode 热题 100】48. 旋转图像——转置+水平翻转
java·算法·leetcode·职场和发展
好开心啊没烦恼2 小时前
Python 数据分析:numpy,说人话,说说数组维度。听故事学知识点怎么这么容易?
开发语言·人工智能·python·数据挖掘·数据分析·numpy
Dcs2 小时前
超强推理不止“大”——手把手教你部署 Mistral Small 3.2 24B 大模型
java
简佐义的博客2 小时前
破解非模式物种GO/KEGG注释难题
开发语言·数据库·后端·oracle·golang