java单例中的饱汉模式实现

饱汉模式即懒加载单例,首次使用时创建实例以避免资源浪费。基本实现线程不安全,同步方法保证安全但性能差,双重检查锁定通过volatile与同步块结合实现高效安全,静态内部类利用JVM机制实现更优雅的懒加载,两者为推荐方式。

饱汉模式,也叫懒加载模式,指的是单例类在第一次被使用时才创建实例。这种方式可以延迟加载,避免资源浪费,但需要处理多线程并发访问的问题。

基本懒加载实现(线程不安全)

注意:下面这种写法在多线程环境下可能创建多个实例,不推荐用于生产环境。

说明:只有在调用 getInstance 方法时才创建对象。

代码示例:
public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {}

    publi

c static LazySingleton getInstance() {
        if (instance == null) {
            instance = new LazySingleton();
        }
        return instance;
    }
}

同步方法实现(线程安全但性能低)

通过 synchronized 关键字保证线程安全,但每次调用 getInstance 都会加锁,影响性能。

改进方式:
将 getInstance 方法声明为 synchronized。

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

双重检查锁定(推荐写法)

既保证线程安全,又提升性能。只在实例未创建时进行同步,后续直接返回。

关键点:instance 变量需用 volatile 修饰,防止指令重排序导致返回未初始化的对象。

代码实现:
public class LazySingleton {
    private static volatile LazySingleton instance;

    private LazySingleton() {}

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

静态内部类实现(更优雅的懒加载)

JVM 保证类的初始化是线程安全的。内部类在被调用时才加载,实现了真正的懒加载。

这种方式简洁、安全,且无须手动加锁。

public class LazySingleton {
    private LazySingleton() {}

    private static class SingletonHolder {
        private static final LazySingleton INSTANCE = new LazySingleton();
    }

    public static LazySingleton getInstance() {
        return SingletonHolder.INSTANCE;
    }
}

基本上就这些。双重检查和静态内部类是最常用的两种饱汉模式实现方式,根据场景选择即可。