创建型模式-单例模式

单例模式有两种常见的实现方式:饿汉式懒汉式。以下是它们的代码示例:

1. 饿汉式(Eager Initialization)

在类加载时就创建实例,线程安全,适用于单例对象耗费资源较小的场景。

java 复制代码
public class SingletonEager {
    // 在类加载时就创建实例
    private static final SingletonEager instance = new SingletonEager();

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

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

优点

  • 简单直观
  • 线程安全,不需要同步

缺点

  • 即使不使用该实例,类加载时也会创建对象,可能造成资源浪费。

2. 懒汉式(Lazy Initialization)

在第一次调用 getInstance() 时才创建实例,适用于单例对象较耗资源且不一定每次都使用的场景。

2.1 线程不安全的懒汉式:
java 复制代码
public class SingletonLazy {
    // 延迟初始化
    private static SingletonLazy instance;

    // 私有构造方法
    private SingletonLazy() {}

    // 提供全局访问点(线程不安全)
    public static SingletonLazy getInstance() {
        if (instance == null) {
            instance = new SingletonLazy();
        }
        return instance;
    }
}

优点

  • 按需加载,节省资源

缺点

  • 线程不安全,多个线程可能同时创建多个实例
2.2 线程安全的懒汉式(同步方法):
java 复制代码
public class SingletonLazyThreadSafe {
    private static SingletonLazyThreadSafe instance;

    private SingletonLazyThreadSafe() {}

    // 通过同步锁保证线程安全
    public static synchronized SingletonLazyThreadSafe getInstance() {
        if (instance == null) {
            instance = new SingletonLazyThreadSafe();
        }
        return instance;
    }
}

优点

  • 线程安全,简单易懂

缺点

  • 每次获取实例都需要同步,性能开销较大
2.3 双重检查锁(Double-Check Locking):
java 复制代码
public class SingletonLazyDoubleCheck {
    private static volatile SingletonLazyDoubleCheck instance;

    private SingletonLazyDoubleCheck() {}

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

优点

  • 线程安全,且只在第一次创建时进行同步,性能较好

缺点

  • 代码较复杂,需要注意 volatile 的使用

3. 静态内部类(推荐使用)

静态内部类的方式结合了懒汉式和饿汉式的优点,线程安全且高效。

java 复制代码
public class SingletonStaticInnerClass {
    private SingletonStaticInnerClass() {}

    // 静态内部类
    private static class SingletonHolder {
        private static final SingletonStaticInnerClass INSTANCE = new SingletonStaticInnerClass();
    }

    public static SingletonStaticInnerClass getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

优点

  • 利用了类加载机制,保证线程安全
  • 延迟初始化,按需加载
  • 不需要同步,性能较高

这几种方式都可以实现单例模式,具体使用时可以根据项目的实际需求进行选择。

在 JDK 中,单例模式被广泛应用于很多核心类和工具类中。以下是一些经典的 JDK 类或组件使用单例模式的例子:

jdk中使用到的单例模式

1. java.lang.Runtime

Runtime 类用于与 JVM 交互,并提供了管理和控制 JVM 的方法。它使用了饿汉式单例。

java 复制代码
Runtime runtime = Runtime.getRuntime();
  • 使用场景Runtime 提供了 JVM 相关的全局服务,比如执行操作系统命令、获取可用的内存和处理器数量等。
  • 实现 :通过 getRuntime() 方法获取唯一实例,类加载时就创建实例。
2. java.awt.Desktop

Desktop 类提供了一些平台相关的桌面操作功能,如打开浏览器、邮件客户端等。它也是通过单例模式实现的。

java 复制代码
Desktop desktop = Desktop.getDesktop();
  • 使用场景:用于与本地操作系统的桌面功能交互,如打开文件、发送邮件等。
  • 实现 :通过 getDesktop() 方法获取唯一实例。
3. java.lang.System

System 类提供了许多静态方法,用于与系统环境交互,如读取环境变量、标准输入输出等。它虽然没有传统意义的 getInstance(),但其设计本质上是一种单例模式,主要通过静态方法提供系统服务。

java 复制代码
System.out.println("Hello, World!");
  • 使用场景:处理标准输入输出流、系统属性、环境变量等。
  • 实现:通过静态方法提供全局访问,不允许实例化。
4. java.util.logging.LogManager

LogManager 类负责管理全局日志配置,确保整个应用程序中日志记录的一致性。

java 复制代码
LogManager logManager = LogManager.getLogManager();
  • 使用场景:控制全局的日志配置,管理所有的 Logger 实例。
  • 实现:使用单例模式确保只有一个日志管理器实例在运行时存在。
5. java.sql.DriverManager

DriverManager 用于管理数据库驱动程序,并处理与数据库的连接请求。

java 复制代码
Connection connection = DriverManager.getConnection(url, user, password);
  • 使用场景:管理数据库连接,加载和注册 JDBC 驱动程序。
  • 实现:通过静态方法管理数据库连接,全局管理驱动程序的加载。
6. java.util.Calendar

Calendar 类用来操作日期和时间的实例,在一些实现(如 GregorianCalendar)中也使用了单例模式。

java 复制代码
Calendar calendar = Calendar.getInstance();
  • 使用场景:用于日期和时间的计算与操作。
  • 实现 :通过 getInstance() 提供全局访问点。
7. java.nio.file.FileSystems

FileSystems 类用来管理文件系统的访问。

java 复制代码
FileSystem fileSystem = FileSystems.getDefault();
  • 使用场景:获取文件系统的根路径,处理路径的文件操作。
  • 实现 :通过 getDefault() 方法获取默认的文件系统,内部实现单例模式。

总结

这些 JDK 中的类,采用单例模式的原因通常是:

  • 确保系统中某个类只有一个实例,避免资源浪费。
  • 提供全局访问点,使得这些实例能够被多个地方访问和共享。
  • 方便管理与外部系统交互的资源,如日志管理器、数据库连接、文件系统、JVM 资源等。
相关推荐
likuolei23 分钟前
XQuery 完整语法速查表(2025 最新版,XQuery 3.1)
xml·java·数据库
雨中飘荡的记忆28 分钟前
LangChain4j 实战指南
java·langchain
okseekw30 分钟前
Java 中的方法:从定义到重载的完整指南
java
雨中飘荡的记忆31 分钟前
深入理解设计模式之适配器模式
java·设计模式
用户849137175471632 分钟前
生产级故障排查实战:从制造 OOM 到 IDEA Profiler 深度破案
java·jvm
雨中飘荡的记忆35 分钟前
深入理解设计模式之装饰者模式
java·设计模式
雨中飘荡的记忆39 分钟前
秒杀系统设计与实现
java·redis·lua
CryptoPP44 分钟前
使用 KLineChart 这个轻量级的前端图表库
服务器·开发语言·前端·windows·后端·golang
18你磊哥1 小时前
chromedriver.exe的使用和python基本处理
开发语言·python
小坏讲微服务1 小时前
Spring Cloud Alibaba 整合 Scala 教程完整使用
java·开发语言·分布式·spring cloud·sentinel·scala·后端开发