方案一:静态内部类实现单例
- 原理:
- 利用Java类加载机制,静态内部类只有在被使用时才会加载。当外部类被加载时,静态内部类不会被立即加载。只有当调用
getInstance
方法时,静态内部类 Holder
才会被加载,此时会初始化 INSTANCE
实例。由于类加载过程是线程安全的,所以这种方式保证了单例的线程安全性,并且延迟了实例的创建。
- 示例代码如下:
public class Singleton {
private Singleton() {}
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return Holder.INSTANCE;
}
}
- 适用场景:适用于大多数高并发场景,尤其是需要延迟加载单例实例的情况。由于类加载机制的保证,这种方式既简单又高效,无需额外的同步操作。
方案二:枚举实现单例
- 原理:
- Java中的枚举类型在编译时就创建好了所有的枚举实例,并且枚举实例的创建是线程安全的。通过定义一个枚举类型,其只有一个实例,就可以实现单例模式。枚举类型在反序列化时,不会重新创建新的实例,而是返回已有的枚举实例,天然防止了反序列化破坏单例。
- 示例代码如下:
public enum Singleton {
INSTANCE;
// 可以添加其他业务方法
public void doSomething() {
// 业务逻辑
}
}
- 适用场景:适用于需要防止反序列化破坏单例以及需要简洁实现单例的场景。在高并发环境下,枚举实现的单例性能很好,并且代码简洁,无需额外的同步或复杂逻辑。它是实现单例模式的最佳实践之一,尤其适合应用于需要序列化和反序列化的场景。