设计模式之单例模式

单例模式

在 Java 中,单例模式是一种设计模式,用于确保某个类只有一个实例,并提供一个全局访问点来获取该实例。单例模式通常用于需要全局访问点的场景,例如日志记录器、数据库连接池、配置文件管理等。

实现单例模式的关键点是:

  1. 将类的构造函数私有化,防止外部直接实例化该类
  2. 提供一个静态方法来获取类的唯一实例,通常命名为 getInstance()getInstance(int param) 等。

在单例模式中,"懒汉"、"饿汉"和"枚举"是三种常见的实现方式,它们分别指代不同的单例对象创建策略。

  1. 懒汉模式(Lazy Initialization)

    • 懒汉模式是指在首次使用时才创建对象实例的方式。在多线程环境下,需要考虑线程安全性,通常会使用双重检查锁定(Double-Checked Locking)等机制来确保线程安全。

      复制代码
      public class LazySingleton {
          private static LazySingleton instance;
          
          private LazySingleton() {
              // 私有构造方法,避免外部直接实例化
          }
          
          public static LazySingleton getInstance() {
              if (instance == null) {
                  instance = new LazySingleton();
              }
              return instance;
          }
      }

      在上面的代码中,LazySingleton 类采用懒汉模式实现单例模式。在 getInstance 方法中,当第一次调用时会创建单例实例,之后再次调用时直接返回已创建的实例。

      需要注意的是,懒汉模式在多线程环境下可能存在线程安全性问题,可能会导致创建多个实例。为了解决这个问题,可以在 getInstance 方法上加锁,或者使用双重检查锁定等方式来确保线程安全。

      以下是使用双重检查锁定方式实现线程安全的懒汉模式的示例代码:

      复制代码
      public class ThreadSafeLazySingleton {
          private volatile static ThreadSafeLazySingleton instance;
      
          private ThreadSafeLazySingleton() {
              // 私有构造函数,防止外部直接实例化
          }
      
          public static ThreadSafeLazySingleton getInstance() {
              if (instance == null) {
                  synchronized (ThreadSafeLazySingleton.class) {
                      if (instance == null) {
                          instance = new ThreadSafeLazySingleton();
                      }
                  }
              }
              return instance;
          }
      }
  2. 饿汉模式(Eager Initialization)

    • 饿汉模式是指在类加载时就创建对象实例的方式,无论后续是否会被使用到。这种方式简单直接,但可能会导致资源浪费。在多线程环境下,需要注意线程安全问题。

      复制代码
      public class EagerSingleton {
          private static final EagerSingleton instance = new EagerSingleton();
          
          private EagerSingleton() {
              // 私有构造方法,避免外部直接实例化
          }
          
          public static EagerSingleton getInstance() {
              return instance;
          }
      }

      在上面的代码中,EagerSingleton 类采用饿汉模式实现单例模式。在类加载时,静态变量 instance 就被创建并初始化为单例实例,随后通过静态方法 getInstance 返回已创建的实例。

      饿汉模式保证了在多线程环境下也能保持单例的唯一性,因为在类加载时就创建了单例实例。但需要注意的是,由于单例实例在类加载时就被创建,可能会导致资源的浪费,特别是在单例实例较大或者初始化耗时较长的情况下。

      总的来说,饿汉模式适用于单例实例较小且初始化较快的情况,可以确保线程安全性。

  3. 枚举模式(Enum Singleton)

    • 枚举单例模式利用 Java 中的枚举类型来实现单例。枚举类型在 Java 中保证只有一个实例,并且在任何情况下都是单例。这种方式简洁高效,并且天然地提供了线程安全性和防止反序列化重新创建对象的保障。

      复制代码
      public class EnumExample {
          // 定义一个枚举类型表示星期几
          public enum Day {
              MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
          }
      
          public static void main(String[] args) {
              // 使用枚举类型来表示今天是星期几
              Day today = Day.MONDAY;
      
              // 使用枚举类型的常量
              switch (today) {
                  case MONDAY:
                      System.out.println("Today is Monday");
                      break;
                  case TUESDAY:
                      System.out.println("Today is Tuesday");
                      break;
                  // 其他星期的处理
                  default:
                      System.out.println("Today is " + today);
              }
          }
      }

​ 在上面的代码中,我们定义了一个枚举类型 Day 表示星期几,包含了每一天作为枚举常量。在 main 方法中,我们使用枚举类型 Day 来表示今天是星期几,并根据不同的情况输出相应的信息。

枚举模式在实际开发中常用于表示一组相关的常量,例如表示状态、类型等。它提供了一种类型安全的方式来操作这些常量,并且可以让代码更加清晰易懂。

总的来说,懒汉模式 是延迟加载的方式,在需要时才创建实例;饿汉模式 是在类加载时就创建对象实例;而枚举模式利用枚举类型的特性来实现单例,是一种简洁高效的实现方式。

相关推荐
AI人工智能+电脑小能手21 小时前
大白话说Java设计模式-08-建造者模式(业务实战篇)
java·设计模式·建造者模式·架构设计·对象构建
AustinXu1 天前
从 Claude Code 到 Claude Tag,Harness Engineering 走到了组织这一层
设计模式·团队管理
剧中有戏1 天前
单例模式从入门到精通:一个数据库连接池的完整剖析
设计模式
胡萝卜术1 天前
编译期与运行期的双重防线:从 TypeScript 类型之争到 LLM 输出的自动化择优
前端·设计模式·面试
货拉拉技术1 天前
重塑 Agent 度量衡:基于 LLM-as-a-Judge 的离线评估体系与实践
算法·设计模式
KhalilRuan1 天前
设计模式小记
设计模式
卡牌RWA研究院1 天前
Relique:一张精品卡牌如何从收藏品变成可交易的链上资产?
设计模式·金融·区块链·创业创新
剧中有戏2 天前
抽象工厂模式从入门到精通:一个多云存储案例的完整剖析(修订版)
设计模式
breeze jiang2 天前
JavaScript 单例模式:用静态属性保证 Popup 只创建一次
开发语言·javascript·单例模式
MC皮蛋侠客2 天前
Redis 系列(八):缓存设计模式与一致性——从 Cache Aside 到防雪崩
redis·缓存·设计模式