返回

单例模式大全:从写法到破坏方式,一网打尽!

闲谈

单例模式的写法

单例模式的写法有很多种,但最常用的有以下几种:

饿汉式

饿汉式是最简单的一种单例模式,也是最容易理解的。它的基本思想是:在类加载的时候就创建好一个实例,并将其存储在类变量中。这样,当其他地方需要使用这个类的时候,直接返回这个类变量即可。

public class Singleton {

    private static final Singleton instance = new Singleton();

    private Singleton() {}

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

懒汉式

懒汉式也是一种很常见的单例模式。它的基本思想是:在第一次需要使用这个类的时候才创建它的实例。这样可以避免在类加载的时候就创建实例,从而节省内存空间。

public class Singleton {

    private static Singleton instance;

    private Singleton() {}

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

双重检查锁

双重检查锁是一种更加高效的懒汉式单例模式。它的基本思想是:先检查一下实例是否已经创建,如果没有创建,再进行同步锁的创建。这样可以避免在多线程环境下出现重复创建实例的情况。

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;
    }
}

内部类

内部类也是一种很常用的单例模式。它的基本思想是:将实例创建的代码放在一个内部类中,然后在外部类中创建一个静态的内部类引用。这样,当外部类加载的时候,内部类就不会被加载。只有在需要使用内部类的时候,才会加载它。

public class Singleton {

    private static class SingletonHolder {

        private static final Singleton instance = new Singleton();
    }

    private Singleton() {}

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

枚举类

枚举类也是一种很常用的单例模式。它的基本思想是:将实例创建的代码放在一个枚举类中。枚举类中的每个枚举值都对应着一个实例。这样,当枚举类加载的时候,实例就会被创建。

public enum Singleton {

    INSTANCE;

    private Singleton() {}

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

单例模式的破坏方式

单例模式虽然是一种很常用的设计模式,但它也并不是万能的。在某些情况下,单例模式可能会被破坏。

多线程

多线程是最常见的一种单例模式破坏方式。当多个线程同时访问单例类的时候,可能会出现多个实例被创建的情况。为了避免这种情况,需要在单例类的 getInstance() 方法上加锁。

反射

反射也是一种很常见的一种单例模式破坏方式。当使用反射来访问私有构造函数的时候,可能会创建多个实例。为了避免这种情况,需要在私有构造函数上加锁。

序列