返回

单例模式的六种花式写法

Android

在软件开发的浩瀚世界中,单例模式犹如一朵奇葩,以其独特的设计理念和广泛的应用场景而著称。单例模式的精髓在于确保一个类只能有一个实例,这一特性带来了诸多优势,例如节约内存开销、控制对象的生命周期以及实现跨越线程的资源共享。

单例模式的实现方式可谓五花八门,但究其本质,无外乎遵循以下核心原则:将构造函数私有化,并提供一个静态方法用于获取实例。而本文将带领你领略单例模式的六种花式写法,为你展示如何用更优雅、更富创造力的方式实现单例对象。

饿汉式

饿汉式单例模式顾名思义,在类加载时就迫不及待地创建实例,因此这种方式线程安全,但开销较大。

public class Singleton {
    private static 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 Singleton instance;

    private Singleton() {}

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

枚举

枚举单例模式利用了枚举类的特性,即枚举类只有一个实例,且线程安全。

public enum Singleton {
    INSTANCE;

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

内部类

内部类单例模式利用了内部类加载时创建实例的特性,同时保持了线程安全。

public class Singleton {
    private Singleton() {}

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

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

代理

代理单例模式通过创建代理类来实现单例模式,代理类负责创建和管理单例对象。

public class Singleton {
    private Singleton() {}

    private static class SingletonHolder {
        private static Singleton instance = new Singleton();
    }

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

public class SingletonProxy {
    public static Singleton getInstance() {
        return Singleton.getInstance();
    }
}