/**
* 1. 高性能单例模式:饿汉式
* 优点:实现简单,天然线程安全
* 缺点:非懒加载。在类加载时就创建实例,如果创建实例很耗时或占用大量内存,但一直未被使用,会造成资源浪费和启动速度变慢
*/
class Singleton1 {
// 类加载时就创建实例(静态常量)
private static final Singleton1 INSTANCE = new Singleton1();
// 私有构造方法,防止外部通过 new 创建对象
private Singleton1() {
// 可以防止反射破坏单例
if (INSTANCE != null) {
throw new RuntimeException("单例对象已创建");
}
}
// 提供全局访问点
public static Singleton1 getInstance() {
return INSTANCE;
}
}
/**
* 2. 高性能单例模式:懒汉式,双重检查锁定
* 优点:实现了线程安全的懒加载,性能较高
* 缺点:实现相对复杂,需要正确使用 voliate 关键字。
*/
class Singleton2 {
// voliate 防止指令重排序,确保 INSTANCE 变量被正确地初始化。
private static volatile Singleton2 INSTANCE;
// 私有构造方法,防止外部通过 new 创建对象
private Singleton2() {
// 可以防止反射破坏单例
if (INSTANCE != null) {
throw new RuntimeException("单例对象已创建");
}
}
public static Singleton2 getInstance() {
//第一次检查:如果实例已存在,直接返回,避免不必要的同步。
if(INSTANCE == null) {
//同步块:只在实例未创建时才进入,大大减少锁的竞争。
synchronized (Singleton2.class) {
//第二次检查:防止多个线程同时通过第一次检查,并在此等待。
if(INSTANCE == null) {
INSTANCE = new Singleton2();
}
}
}
return INSTANCE;
}
}
/**
* 3. 高性能单例模式:静态内部类
* 优点:代码简洁,完美实现了线程安全的懒加载,性能极高。
* 缺点:无。这是最推荐的实现方式之一。
*/
class Singleton3 {
// 静态内部类,当外部类被加载时,其内部类 SingletonInner 不会立即被加载。
private static class SingletonHolder {
private static final Singleton3 INSTANCE = new Singleton3();
}
public static Singleton3 getInstance() {
// 只有当第一次调用 getInstance() 方法时,JVM 才会加载 SingletonHolder 类。
// 类加载的过程是线程安全的,JVM 会保证 INSTANCE 只被初始化一次。
return SingletonHolder.INSTANCE;
}
// 私有构造方法,防止外部通过 new 创建对象
private Singleton3() {
// 可以防止反射破坏单例
if (SingletonHolder.INSTANCE != null) {
throw new RuntimeException("单例对象已创建");
}
}
}
/**
* 4. 高性能单例模式:枚举(Enum),《Effective Java》作者 Joshua Bloch 极力推崇的方式。
* 它不仅能防止多线程问题,还能自动支持序列化机制,防止反序列化时创建新的对象。
* 优点:实现最简单,天然线程安全,且能防止反序列化创建新对象。
* 缺点:非懒加载(与饿汉式类似),且无法继承其他类。
*/
enum Singleton4 {
INSTANCE;
public void doSomething() {
System.out.println("xxx");
}
}
public class Main{
public static void main(String[] args) {
//1. 高性能单例模式:饿汉式
Singleton1 s1 = Singleton1.getInstance();
System.out.println(s1);
//2. 高性能单例模式:懒汉式,双重检查锁定
Singleton2 s2 = Singleton2.getInstance();
System.out.println(s2);
//3. 高性能单例模式:静态内部类
Singleton3 s3 = Singleton3.getInstance();
System.out.println(s3);
//4. 高性能单例模式:直接整个枚举
Singleton4 s4 = Singleton4.INSTANCE;
s4.doSomething();
}
}