单例模式(Singleton Pattern)是设计模式中最常用的一种,它确保一个类只有一个实例,并提供一个全局访问点。在Java中实现单例模式有多种方法,以下将详细介绍五种常用的实现方式,并分析它们的优缺点。
1. 懒汉式(懒加载)
懒汉式单例模式在第一次使用时才创建实例,延迟了实例的创建时间,节省了资源。
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
优点:延迟加载,节省资源。
缺点:线程不安全,在高并发环境下可能导致多个实例的创建。
2. 饿汉式(饿加载)
饿汉式单例模式在类加载时就创建了实例,保证了实例的唯一性。
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {}
public static EagerSingleton getInstance() {
return instance;
}
}
优点:线程安全,实例唯一。
缺点:类加载时就创建了实例,可能会占用不必要的资源。
3. 静态内部类
静态内部类单例模式利用静态内部类和Java类加载机制保证实例的唯一性。
public class StaticInnerClassSingleton {
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}
private StaticInnerClassSingleton() {}
public static final StaticInnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
优点:线程安全,延迟加载。
缺点:代码稍显复杂。
4. 双重校验锁
双重校验锁单例模式在确保线程安全的同时,避免了同步带来的性能损耗。
public class DoubleCheckedLockingSingleton {
private volatile static DoubleCheckedLockingSingleton instance;
private DoubleCheckedLockingSingleton() {}
public static DoubleCheckedLockingSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedLockingSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedLockingSingleton();
}
}
}
return instance;
}
}
优点:线程安全,性能较高。
缺点:代码较为复杂。
5. 枚举单例
枚举单例是一种最简单、最安全的单例实现方式。
public enum EnumSingleton {
INSTANCE;
public void someMethod() {
// 实现方法
}
}
优点:线程安全,简洁易读。
缺点:代码可读性较差。
总结
以上五种Java单例模式实现方式各有优缺点,选择哪种方式取决于具体场景和需求。在实际开发中,建议根据实际情况选择合适的单例模式实现方式。
