MST

星途 面试题库

面试题:Java 中单例模式的饿汉式与懒汉式实现及区别

请分别用 Java 实现单例模式的饿汉式和懒汉式,并阐述两者在实现原理、线程安全性以及应用场景上有什么区别。
33.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

饿汉式实现

public class EagerSingleton {
    private static final EagerSingleton instance = new EagerSingleton();

    private EagerSingleton() {}

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

懒汉式实现(线程不安全版本)

public class LazySingleton {
    private static LazySingleton instance;

    private LazySingleton() {}

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

懒汉式实现(线程安全版本,使用 synchronized 关键字)

public class ThreadSafeLazySingleton {
    private static ThreadSafeLazySingleton instance;

    private ThreadSafeLazySingleton() {}

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

实现原理区别

  • 饿汉式:在类加载时就立即创建实例,不管是否需要使用该实例。
  • 懒汉式:只有在第一次调用 getInstance 方法时才创建实例。

线程安全性区别

  • 饿汉式:天生线程安全,因为实例在类加载时就创建好了,不存在多线程同时创建实例的问题。
  • 懒汉式:普通懒汉式实现线程不安全,因为在多线程环境下,可能会有多个线程同时判断 instance == null 为真,从而创建多个实例。线程安全版本的懒汉式通过 synchronized 关键字保证同一时间只有一个线程可以进入 getInstance 方法创建实例。

应用场景区别

  • 饿汉式:适用于实例创建开销不大,且应用程序启动后很快就会使用该实例的场景,或者要求绝对线程安全的场景。
  • 懒汉式:适用于实例创建开销较大,且在应用程序启动初期不需要立即使用该实例的场景,以节省内存资源。线程安全版本懒汉式虽然保证了线程安全,但由于 synchronized 关键字的存在,性能会有所损耗,在高并发场景下使用需要权衡。