单例模式,饿汉式,懒汉式,在java和spring中的体现

目录

饿汉式单例模式

懒汉式单例模式

Spring中的单例模式

关键差异对比

在Java和Spring中的应用场景

手写案例

单例模式是一种创建型设计模式,其核心在于确保一个类仅有一个实例,并提供一个全局访问点来获取该实例。下面将详细介绍饿汉式和懒汉式单例模式,以及它们在Java和Spring框架中的体现。

饿汉式单例模式

这种模式的特点是类加载时就创建实例,无需等待首次使用。它不存在线程安全问题,因为实例的创建是在类加载阶段完成的。

Java实现示例

复制代码
public class EagerSingleton {
    private static final EagerSingleton INSTANCE = new EagerSingleton();

    private EagerSingleton() {}

    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
}

懒汉式单例模式

懒汉式单例模式是在首次使用时才创建实例。不过,在多线程环境下,如果没有合适的同步机制,就可能会创建多个实例。

非线程安全的Java实现示例

复制代码
public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {}

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

线程安全的Java实现示例

复制代码
public class ThreadSafeLazySingleton {
    private static volatile ThreadSafeLazySingleton instance;

    private ThreadSafeLazySingleton() {}

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

Spring中的单例模式

在Spring框架里,默认情况下,所有的bean都是以单例模式创建的,也就是在整个应用上下文中只存在一个实例。

Spring单例bean示例

复制代码
@Component
public class SpringSingleton {
    // Spring会自动管理这个bean的单例实例
}

获取Spring单例bean的方式

复制代码
@Autowired
private SpringSingleton springSingleton;

关键差异对比

|------------|-----------------|------------------|
| 维度 | 饿汉式 | 懒汉式(线程安全) |
| 实例创建时机 | 类加载时 | 首次调用时 |
| 线程安全性 | 安全 | 安全 |
| 优点 | 实现简单,无需考虑线程安全问题 | 延迟加载,节省资源 |
| 缺点 | 可能造成资源浪费 | 实现较为复杂,性能可能受影响 |
| 适用场景 | 实例创建成本低,且一定会被使用 | 实例创建成本高,或不一定会被使用 |

在Java和Spring中的应用场景

  • Java中的应用:像日志记录器、数据库连接池这类需要全局唯一实例的场景,会用到单例模式。
  • Spring中的应用:Spring框架默认将bean配置为单例,这样可以减少内存开销,同时保证状态管理的一致性。

理解单例模式的不同实现方式以及它们在Java和Spring中的应用,有助于设计出高效且线程安全的应用程序。

手写案例

复制代码
public class Main { }

// 单例模式 初始化bean

// 饿汉式 单例初始化
// 在类首次加载时就进行初始化 不需要考虑线程安全问题
class  Hungrybean{
    private static final Hungrybean INSTANCE = new Hungrybean();
    public static Hungrybean getInstance() {
        return INSTANCE;
    }
}

// 懒汉式 单例初始化
// 在使用时再进行初始化 可能存在线程安全问题
class  Lazybean{
    private static Lazybean INSTANCE ;
    public static Lazybean getInstance() {
        if(INSTANCE==null){
            INSTANCE=new Lazybean();
        }
        return INSTANCE;
    }
}

// 锁机制 修复了懒汉是的线程安全问题
class ThreadSafeLazybean{
    private static ThreadSafeLazybean INSTANCE;
    public static ThreadSafeLazybean getInstance(){
        if(INSTANCE==null){
            synchronized (ThreadSafeLazybean.class){
                if (INSTANCE==null){
                    INSTANCE=new ThreadSafeLazybean();
                }
                return INSTANCE;
            }
        }
    }
}
相关推荐
oradh15 分钟前
Oracle XTTS实现跨版本迁移和升级(Oracle 11g单库升级至19C RAC集群)
数据库·oracle·11g升级19c·xtts跨版本迁移和升级
程序员cxuan32 分钟前
Grok Build 被众人唾骂,结果老马把它开源了
人工智能·后端·程序员
莫逸风32 分钟前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
从零开始的代码生活_34 分钟前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
云小逸38 分钟前
【C++ 第七阶段:模板、泛型编程与工程综合详解】
开发语言·c++
Conan在掘金1 小时前
�鸿蒙报错速查:Cannot find name 'require',禁用 require(),根因 + 真解法
后端
隔窗听雨眠1 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
一朵小花1 小时前
记一次Docker 容器 NFS 文件写入延迟排查过程
后端
z123456789861 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
程序猿DD1 小时前
一个 API Key,统一调用大模型、生图和联网搜索
数据库·网关