单例模式中的饿汉式

1. 饿汉式单例完整代码(基础版)

java 复制代码
// 饿汉式单例:类加载时就创建实例
public class EagerSingleton {
    // 关键点1:静态私有变量,类加载时初始化实例
    // static:属于类,全局唯一;final:确保实例不可被替换;private:禁止外部直接访问
    private static final EagerSingleton INSTANCE = new EagerSingleton();

    // 关键点2:私有化构造器,阻止外部通过new创建实例
    private EagerSingleton() {
        // 可以在构造器中添加初始化逻辑(如初始化资源)
        System.out.println("饿汉式单例实例被创建了");
    }

    // 关键点3:公开静态方法,提供全局访问点
    public static EagerSingleton getInstance() {
        return INSTANCE; // 直接返回预创建的实例
    }

    // 测试方法:验证实例唯一性
    public void doSomething() {
        System.out.println("当前实例地址:" + this);
    }

    // 主方法测试
    public static void main(String[] args) {
        // 尝试创建多个实例
        EagerSingleton s1 = EagerSingleton.getInstance();
        EagerSingleton s2 = EagerSingleton.getInstance();

        // 调用方法,观察实例地址是否相同
        s1.doSomething(); // 输出:当前实例地址:EagerSingleton@xxxxxxx
        s2.doSomething(); // 输出:当前实例地址:EagerSingleton@xxxxxxx(与s1相同)

        // 验证:s1和s2是否为同一个对象
        System.out.println("s1 == s2 ? " + (s1 == s2)); // 输出:true(证明唯一)
    }
}

2. 运行结果解析

  • 程序启动时,EagerSingleton类加载,会立即执行new EagerSingleton(),打印 "饿汉式单例实例被创建了"(类加载阶段初始化)。
  • 调用getInstance()两次,返回的s1s2地址完全相同(==结果为true),证明全局只有一个实例。
  • 无法通过new EagerSingleton()创建实例(构造器私有,编译报错),确保了实例唯一性。

3. 多线程环境下的线程安全测试

饿汉式天生线程安全,因为类加载过程由 JVM 保证同步,以下代码验证:

java 复制代码
public class EagerSingletonThreadTest {
    public static void main(String[] args) {
        // 启动10个线程,同时获取实例
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                EagerSingleton instance = EagerSingleton.getInstance();
                System.out.println("线程" + Thread.currentThread().getId() + "获取的实例:" + instance);
            }).start();
        }
    }
}

运行结果:所有线程打印的实例地址完全相同,证明多线程环境下不会创建多个实例(线程安全)。

4. 饿汉式的局限性示例(资源浪费场景)

如果单例实例初始化成本高(如加载大文件),但程序可能用不到,会浪费资源:

java 复制代码
public class ResourceHeavyEagerSingleton {
    // 假设初始化需要加载100MB的配置文件(模拟高成本)
    private static final ResourceHeavyEagerSingleton INSTANCE = new ResourceHeavyEagerSingleton();

    private ResourceHeavyEagerSingleton() {
        System.out.println("加载100MB配置文件...(耗时操作)");
    }

    public static ResourceHeavyEagerSingleton getInstance() {
        return INSTANCE;
    }

    public static void main(String[] args) {
        System.out.println("程序启动,但暂时不需要用这个单例...");
        // 此时,即使没调用getInstance(),实例也已创建并加载了资源(浪费)
    }
}

运行结果:程序启动后,会直接打印 "加载 100MB 配置文件...(耗时操作)",即使从未使用该实例,资源已被消耗。

总结

饿汉式单例通过类加载时初始化静态实例 + 私有构造器 + 静态访问方法的组合,实现了:

  1. 实例唯一性(禁止外部创建,全局仅一个);
  2. 线程安全性(JVM 类加载机制保证);
  3. 简单直接的实现(无需处理同步逻辑)。

但需注意:如果实例初始化成本高且可能不被使用,会造成资源浪费,这种场景下需考虑懒汉式等其他实现。

相关推荐
uzong21 小时前
程序员从大厂回重庆工作一年
java·后端·面试
kyle~21 小时前
C++---value_type 解决泛型编程中的类型信息获取问题
java·开发语言·c++
NiNi_suanfa1 天前
【Qt】Qt 批量修改同类对象
开发语言·c++·qt
小糖学代码1 天前
LLM系列:1.python入门:3.布尔型对象
linux·开发语言·python
Data_agent1 天前
1688获得1688店铺详情API,python请求示例
开发语言·爬虫·python
妖灵翎幺1 天前
C++ 中的 :: 操作符详解(一切情况)
开发语言·c++·ide
开心香辣派小星1 天前
23种设计模式-15解释器模式
java·设计模式·解释器模式
Halo_tjn1 天前
虚拟机相关实验概述
java·开发语言·windows·计算机
star _chen1 天前
C++实现完美洗牌算法
开发语言·c++·算法
周杰伦fans1 天前
pycharm之gitignore设置
开发语言·python·pycharm