单例模式


单例模式

什么是单例模式

单例模式是一种创建型设计模式,它的目的是确保一个类只有一个实例,并提供对该实例的全局访问点。

它通常适用于需要对某个资源(如数据库连接池、日志输出等)进行管理的情况,以避免多个实例竞争资源造成的冲突。

为什么需要单例模式

在实际的应用中,有些情景需要我们仅仅只想获取或使用某个类的一个实例,而不是多个实例。这时候就需要使用单例模式。

单例模式可以避免由于多次实例化而造成的资源浪费。同时也避免了多个实例之间互相调用而导致的冲突。

因此,我们必须要确保某个类始终只有一个实例。参考 JDK 中的 java.lang.Runtimejava.awt.Desktop 类。

如何实现单例模式

懒汉式

懒汉式指的是当我们需要使用这个类的实例时,才去创建它。

public class Singleton {
    private static Singleton singletonInstance = null;

    private Singleton() {}

    public static Singleton getInstance() {
        if (singletonInstance == null) {
            singletonInstance = new Singleton();
        }
        return singletonInstance;
    }
}

饿汉式

饿汉式指的是在类加载时就已经初始化好了实例,可以在后面的调用过程中直接获取实例。

public class Singleton {
    private static final Singleton singletonInstance = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return singletonInstance;
    }
}

双重检验锁

双重检验锁的核心在于一个 volatile 类型的变量和一个加锁的代码块。

public class Singleton {
    private static volatile Singleton singletonInstance = null;

    private Singleton() {}

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

静态内部类

静态内部类指的是将单例类放到静态内部类中,只有在第一次调用时,才会去实例化一个单例的 AbstractSingleton。

public class Singleton {
    private static class SingletonHolder {
        private static final Singleton singletonInstance = new Singleton();
    }

    private Singleton() {}

    public static Singleton getInstance() {
        return SingletonHolder.singletonInstance;
    }
}

枚举

枚举相当于一种更加简化的静态内部类的版本,在这种情况下,枚举被当作是一种单例的实现方式。

public enum Singleton {
    INSTANCE;

    public void doSomething() {
        // ...
    }
}

单例模式的优缺点

优点

  1. 确保一个类只有一个实例,避免多次实例化造成的资源浪费。
  2. 提供对唯一实例的全局访问点,方便对该实例的控制。

缺点

  1. 单例模式一般违反了单一职责原则,因为它同一时间只能做一件事情。
  2. 单例模式可能导致一些设计问题,如难以测试、容易被其他代码调用等。
  3. 单例模式可能导致不必要的延迟加载,即在使用时才去实例化一个单例实例,这个过程有时候可能会使应用变慢。

总结

单例模式是一种非常实用的设计模式,在需要对某个资源进行统一管理且不会存在多个实例时可以使用。

我们可以采用懒汉式、饿汉式、双重检验锁、静态内部类、枚举等方式来实现单例模式。

单例模式的优点在于确保了类只有一个实例,并提供对该实例的全局访问点。但是缺点也显而易见,可能违反单一职责原则,也可能出现设计问题以及不必要的延迟加载等。

参考文献

  1. Design Patterns: Singleton Pattern
  2. Singleton pattern - Wikipedia
  3. Singleton 模式详解及其在 Android 中的应用