设计模式-单例模式

单例模式(Singleton Pattern)解释

定义
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来获取它。


单例模式的特点

  1. 全局唯一性:单例类只能有一个实例。
  2. 全局访问点:通过提供一个静态方法或属性,允许其他类访问该唯一实例。
  3. 懒加载:实例在第一次使用时创建,避免不必要的资源消耗(可选)。

单例模式的实现方式

以下用 Java 示例讲解常见的单例模式实现方式。


1. 饿汉式(Eager Initialization)

在类加载时就创建实例,线程安全,但如果实例未被使用会浪费资源。

public class Singleton {
    // 静态实例,类加载时初始化
    private static final Singleton INSTANCE = new Singleton();

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

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

优点:实现简单,线程安全。
缺点:类加载时就创建实例,即使未使用也会占用资源。


2. 懒汉式(Lazy Initialization)

在需要时才创建实例,线程不安全。

public class Singleton {
    private static Singleton instance;

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

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

优点:实例在第一次使用时创建,避免资源浪费。
缺点:多线程环境下可能导致线程安全问题。


3. 线程安全的懒汉式

通过 synchronized 关键字解决线程安全问题。

public class Singleton {
    private static Singleton instance;

    private Singleton() {}

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

优点:线程安全,懒加载。
缺点:性能较低,每次获取实例时都需要同步。


4. 双重检查锁(Double-Checked Locking)

结合懒加载和线程安全,推荐使用。

public class Singleton {
    private static volatile Singleton instance;

    private Singleton() {}

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

优点:线程安全,性能高,推荐使用。
缺点:实现稍复杂,使用了 volatile 关键字确保变量可见性。


5. 静态内部类

利用 Java 的类加载机制,线程安全且支持懒加载。

public class Singleton {
    private Singleton() {}

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

    // 提供全局访问点
    public static Singleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

优点:线程安全,懒加载,性能高。
缺点:实现稍复杂。


6. 枚举单例

通过枚举实现单例模式,是最简单和推荐的方式之一。

public enum Singleton {
    INSTANCE;

    public void doSomething() {
        System.out.println("单例方法调用");
    }
}

优点:天生线程安全,防止反序列化破坏单例,代码简单。
缺点:不支持延迟加载(但通常这不是问题)。


测试单例模式

public class SingletonTest {
    public static void main(String[] args) {
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();

        System.out.println(singleton1 == singleton2); // true,两个引用指向同一个实例
    }
}

单例模式的优缺点

优点

  1. 唯一实例:确保系统中只有一个对象,节省资源。
  2. 全局访问:提供一个全局访问点,便于管理。

缺点

  1. 扩展困难:由于类只能有一个实例,继承和扩展较难。
  2. 并发问题:某些实现方式在多线程环境下可能不安全。

使用场景

  1. 日志记录器:系统中的日志类只需要一个实例。
  2. 配置管理:全局配置类,避免重复加载配置。
  3. 数据库连接池:确保多个模块共享同一个连接池。
  4. 线程池:单例模式可用于管理线程池的全局访问。

通过以上方式,可以根据需求和场景选择合适的单例模式实现方式。

posted @ 2025-01-15 09:03  庞某人  阅读(50)  评论(0)    收藏  举报