专业编程基础技术教程

网站首页 > 基础教程 正文

单例模式(单例模式java实现)

ccvgpt 2025-06-18 19:29:17 基础教程 1 ℃

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

常见的实现方式有Eager Initialization和Lazy Initialization.

单例模式(单例模式java实现)

Eager Initialization 预先初始化(饿汉模式)

核心特点:类加载时就创建实例(急切初始化)
线程安全性:天生线程安全
内存考虑:可能造成资源浪费(未使用时也占用内存)

public class EagerSingleton {
    // 类加载时立即创建唯一实例(final防止被修改)
    private static final EagerSingleton INSTANCE = new EagerSingleton();

    // 私有构造器阻止外部创建实例
    private EagerSingleton() {
        // 初始化代码
    }

    // 全局访问点
    public static EagerSingleton getInstance() {
        return INSTANCE;
    }
}

优点

  • 实现简单,线程安全(JVM类加载机制保证)
  • 无同步开销

缺点

  • 如果实例未被使用,会造成内存浪费
  • 无法延迟初始化(不能依赖配置参数)

Lazy Initialization 延迟初始化(懒汉模式)

核心特点:首次访问时才创建实例(延迟初始化)
线程安全性:需自行保证(需处理多线程问题)

版本1:基础版(线程不安全)

public class UnsafeLazySingleton {
    private static UnsafeLazySingleton instance;

    private UnsafeLazySingleton() {}

    public static UnsafeLazySingleton getInstance() {
        if (instance == null) { // 竞态条件下可能创建多个实例
            instance = new UnsafeLazySingleton();
        }
        return instance;
    }
}

版本2:同步方法(性能差)

public class SynchronizedLazySingleton {
    private static SynchronizedLazySingleton instance;

    private SynchronizedLazySingleton() {}

    // 每次调用都同步,性能损失
    public static synchronized SynchronizedLazySingleton getInstance() {
        if (instance == null) {
            instance = new SynchronizedLazySingleton();
        }
        return instance;
    }
}

版本3:双重校验锁(推荐)

public class DoubleCheckedLockingSingleton {
    // volatile禁止指令重排序(确保线程安全)
    private volatile static DoubleCheckedLockingSingleton instance;

    private DoubleCheckedLockingSingleton() {}

    public static DoubleCheckedLockingSingleton getInstance() {
        if (instance == null) { // 第一次检查(避免每次加锁)
            synchronized (DoubleCheckedLockingSingleton.class) {
                if (instance == null) { // 第二次检查(防止多线程多次创建)
                    instance = new DoubleCheckedLockingSingleton();
                }
            }
        }
        return instance;
    }
}

版本4:静态内部类(最佳实践)

public class InnerClassSingleton {
    private InnerClassSingleton() {}

    // 静态内部类在首次使用时加载
    private static class Holder {
        static final InnerClassSingleton INSTANCE = new InnerClassSingleton();
    }

    public static InnerClassSingleton getInstance() {
        return Holder.INSTANCE; // 线程安全由JVM类加载机制保证
    }
}

优点

  • 延迟初始化,资源利用率高
  • 静态内部类实现无同步开销,线程安全(推荐方式)

核心对比

特性

饿汉模式

懒汉模式

初始化时机

类加载时立即初始化

首次调用时初始化

线程安全

天生安全

需额外同步机制

资源效率

可能浪费内存

按需加载,资源更高效

实现复杂度

简单直接

双重检查/内部类较复杂

序列化安全性

需处理readResolve()

需处理readResolve()


最佳实践建议

  1. 优先使用静态内部类实现懒汉模式
    延迟加载 + 无同步开销 + JVM保障安全
  2. 需要明确控制加载顺序时选用饿汉模式
  3. 避免基础懒汉模式(线程不安全)和同步方法懒汉(性能低)

场景示例

  • 饿汉模式适用
    实例初始化开销小且必然被使用(如配置管理器)
  • 懒汉模式适用
    实例初始化耗资源(如数据库连接池)或启动参数依赖

Tags:

最近发表
标签列表