单例模式 Java 实现

单例模式是一种创建型设计模式,用于确保一个类只有一个实例,并提供全局访问点。在 Java 中,单例模式主要有两种常见的实现方式:饿汉式和懒汉式。

饿汉式单例

饿汉式单例在类加载时就创建了实例,并且在整个应用程序的生命周期中只有一个实例存在。下面是饿汉式单例的实现代码示例:

public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();

    // 私有构造方法,防止外部实例化
    private EagerSingleton() {}

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

上述代码中,EagerSingleton 类的构造方法被声明为私有的,以防止其他类通过 new 关键字来创建实例。instance 字段是一个静态常量,用于保存类的唯一实例。getInstance 方法是一个静态方法,返回 instance 字段的值。

懒汉式单例

懒汉式单例只有在第一次使用时才会创建实例,这样可以节约资源。下面是懒汉式单例的实现代码示例:

public class LazySingleton {
    private static LazySingleton instance;

    // 私有构造方法,防止外部实例化
    private LazySingleton() {}

    // 全局访问点
    public static synchronized LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

上述代码中,LazySingleton 类的构造方法和 getInstance 方法与饿汉式单例相同。不同之处在于,instance 字段不再是一个静态常量,而是一个静态变量。getInstance 方法采用了懒加载(lazy loading)的方式,即在第一次调用时才会创建实例。

需要注意的是,懒汉式单例在多线程环境下可能会出现线程安全问题。为了解决这个问题,可以在 getInstance 方法上加上 synchronized 关键字,以保证在同一时间只有一个线程能够访问该方法。

类图

下面是单例模式的类图:

classDiagram
    class Singleton {
        <<interface>>
        +getInstance(): Singleton
    }
    class EagerSingleton {
        -instance: EagerSingleton
        +getInstance(): EagerSingleton
    }
    class LazySingleton {
        -instance: LazySingleton
        +getInstance(): LazySingleton
    }
    Singleton <|.. EagerSingleton
    Singleton <|.. LazySingleton

流程图

下面是 EagerSingleton 的创建流程图:

flowchart TD
    Start --> 判断 instance 是否为 null
    判断 instance 是否为 null -->|是| 创建 EagerSingleton 实例
    创建 EagerSingleton 实例 --> 返回实例
    判断 instance 是否为 null -->|否| 返回实例
    返回实例 --> Stop

下面是 LazySingleton 的创建流程图:

flowchart TD
    Start --> 判断 instance 是否为 null
    判断 instance 是否为 null -->|是| 创建 LazySingleton 实例
    创建 LazySingleton 实例 --> 返回实例
    判断 instance 是否为 null -->|否| 返回实例
    返回实例 --> Stop

总结

单例模式是一种常见且有用的设计模式,用于确保一个类只有一个实例,并提供全局访问点。在 Java 中,饿汉式和懒汉式是两种常见的单例实现方式。

饿汉式单例在类加载时就创建了实例,因此是线程安全的。懒汉式单例在第一次使用时才创建实例,因此需要考虑线程安全性。

无论使用哪种方式,单例模式都可以提供全局访问点,方便地在任何地方获取相同的实例。在设计应用程序时,根据实际需求选择适合的单例实现方式。