返回

重塑单例模式,从基础到卓越

后端

单例模式,作为设计模式中的经典,却常被简化成仅有的懒汉和饿汉之争。本文将深入剖析单例模式,从基础到最优,再到额外推荐的写法,助你面试中如鱼得水,疯狂加分!

基础篇:懒汉模式和饿汉模式

懒汉模式

惰于初始化,只有在第一次调用时才会创建实例:

public class Singleton {
    private static Singleton instance;

    private Singleton() { }

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

饿汉模式

急于初始化,在类加载时就创建实例:

public class Singleton {
    private static Singleton instance = new Singleton();

    private Singleton() { }

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

进阶篇:最优写法

静态内部类

巧用静态内部类,既能实现延迟加载,又能保证线程安全:

public class Singleton {
    private Singleton() { }

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

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

枚举

枚举本身就是单例的,代码简洁,性能优异:

public enum Singleton {
    INSTANCE;

    public void doSomething() { ... }
}

拓展篇:额外推荐

双重锁校验

在懒汉模式的基础上,通过双重锁校验优化并发性能:

public class Singleton {
    private volatile static Singleton instance;

    private Singleton() { }

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

注册式单例

适合需要创建多个实例的场景,通过注册中心管理实例:

public class SingletonFactory {
    private static Map<String, Singleton> instances = new HashMap<>();

    public static Singleton getInstance(String key) {
        if (!instances.containsKey(key)) {
            instances.put(key, new Singleton(key));
        }
        return instances.get(key);
    }
}

public class Singleton {
    private String key;

    private Singleton(String key) {
        this.key = key;
    }
}

总结

单例模式不只是懒汉和饿汉,还有更优雅的写法。通过了解基础、进阶、拓展篇的内容,你可以加深对单例模式的理解,在面试中游刃有余,脱颖而出。