设计模式 - 创建型 - 单例模式(Singleton pattern)

一、以下是Java中创建单例模式的几种常见方法,每种方法都有其特点和适用场景

1. 使用枚举实现线程安全的单例模式
Joshua Bloch推荐的线程安全实现方式,还能防止反序列化破坏单例

public enum SingletonEnum {
    INSTANCE;
    
    private final DatabaseService databaseService;
    
    private SingletonEnum() {
        this.databaseService = new DatabaseService();
    }
    
    public DatabaseService getDatabaseService() {
        return databaseService;
    }
}

class DatabaseService {
    public void executeQuery(String query) {
        System.out.println("Executing query: " + query);
    }
}

class MainTest {
    public static void main(String[] args) {
        DatabaseService service1 = SingletonEnum.INSTANCE.getDatabaseService();
        DatabaseService service2 = SingletonEnum.INSTANCE.getDatabaseService();
        
        service1.executeQuery("SELECT * FROM users");
        System.out.println("Is same instance: " + (service1 == service2));
    }
}

‌2. 饿汉式单例‌
类加载时就初始化实例,线程安全但可能造成资源浪费

public class Singleton {
    private static final Singleton instance = new Singleton();
    private Singleton() {}
    public static Singleton getInstance() {
        return instance;
    }
}

‌3. 懒汉式单例(线程不安全)‌
延迟加载但多线程环境下可能创建多个实例

public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

‌4. 线程安全的懒汉式‌
通过synchronized保证线程安全,但性能较低

public class Singleton {
    private static Singleton instance;
    private Singleton() {}
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

‌5. 双重校验锁(DCL)‌
线程安全且性能较好,需配合volatile使用

public class Singleton {
    private static volatile Singleton instance;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

‌6. 静态内部类实现‌
线程安全且实现懒加载,推荐方式之一

public class Singleton {
    private Singleton() {}
    private static class Holder {
        static final Singleton INSTANCE = new Singleton();
    }
    public static Singleton getInstance() {
        return Holder.INSTANCE;
    }
}

‌7. 容器式单例‌(饿汉式单例‌的变种)
适用于管理多个单例对象,如Spring容器实现

public class SingletonManager {
    private static Map<String, Object> instances = new ConcurrentHashMap<>();
    public static void register(String key, Object instance) {
        if (!instances.containsKey(key)) {
            instances.put(key, instance);
        }
    }
    public static Object getInstance(String key) {
        return instances.get(key);
    }
}

二、 优势对比

以下是枚举单例与其他单例实现方式的对比分析,从线程安全、反序列化防护、反射防护、实现复杂度等维度综合评估:

在这里插入图片描述
★ 关键结论:

  1. 枚举单例在安全性上全面领先
  2. 静态内部类是延迟加载的最佳备选
  3. 避免使用非线程安全的懒汉式

枚举实现单例是《Effective Java》推荐的最佳实践,适合需要高安全性和简洁性的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值