在 Java 中实现单例设计模式主要有几种方式,每种方式都有其适用场景及优缺点。单例模式的目的是确保一个类只有一个实例,并提供一个全局访问点。以下是一些常见的实现方法:
懒汉式(Lazy Initialization)
该模式只有在需要时才实例化单例,但未考虑多线程环境,不是线程安全的。
public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}
为了使其在多线程环境下安全,可以在 getInstance
方法上添加 synchronized
关键字,但这会影响性能。
public static synchronized LazySingleton getInstance() {// ...
}
或者使用双重检查锁定(Double-checked locking)方式来减少同步的开销:
public class LazySingleton {private static volatile LazySingleton instance; // 使用volatile关键字private LazySingleton() {}public static LazySingleton getInstance() {if (instance == null) {synchronized (LazySingleton.class) {if (instance == null) {instance = new LazySingleton();}}}return instance;}
}
饿汉式(Eager Initialization)
该模式在类加载时就已经创建好了单例,因此不存在多线程问题,但可能提前占用资源。
public class EagerSingleton {private static final EagerSingleton instance = new EagerSingleton();private EagerSingleton() {}public static EagerSingleton getInstance() {return instance;}
}
静态内部类(Static Inner Class)
利用 JVM 保证只会执行一次类的初始化锁,这种方式没有性能缺陷,也不依赖 synchronized
。
public class StaticInnerSingleton {private StaticInnerSingleton() {}private static class SingletonHolder {private static final StaticInnerSingleton INSTANCE = new StaticInnerSingleton();}public static StaticInnerSingleton getInstance() {return SingletonHolder.INSTANCE;}
}
枚举(Enum)
从 Java 1.5 开始,可以使用枚举来实现单例模式。这种方式提供了序列化机制,并提供了对单例破坏的保护。
public enum EnumSingleton {INSTANCE;public void someMethod() {// 功能实现}
}
使用时直接通过 EnumSingleton.INSTANCE
获取实例。
每种实现方法都有其适用场景,具体选择哪种方式取决于你的应用需求,比如对延时加载、性能、资源使用、复杂性以及 Java 版本的要求等。在多数情况下,推荐使用静态内部类或者枚举的方式来实现单例模式。