java设计模式:02-01-单例模式

单例模式(Singleton Pattern)

单例模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点来访问该实例。单例模式通常用于需要全局唯一实例的场景,例如:

  • 日志记录(Logging):应用程序中的所有组件都需要记录日志,单例模式可以确保日志记录器的唯一实例。
  • 配置管理(Configuration Management):配置文件的读取和写入需要全局唯一实例,以避免不同组件之间的配置不一致。
  • 连接池(Connection Pooling):数据库连接池需要管理有限数量的连接实例,单例模式可以确保连接池的唯一实例。
  • 缓存(Caching):全局缓存需要唯一实例,以便于所有组件共享缓存数据。
  • 线程池(Thread Pool):线程池需要全局唯一实例,以确保系统中只有一个线程池在管理线程。

单例模式的多种实现方式

1. 饿汉式(Eager Initialization)

思想:在类加载时就创建单例实例,避免了多线程问题,但如果实例占用资源较大且不一定会用到,会造成资源浪费。

实现方式

public class SingletonEager {
    private static final SingletonEager INSTANCE = new SingletonEager();

    private SingletonEager() {
        // 防止实例化的私有构造函数
    }

    public static SingletonEager getInstance() {
        return INSTANCE;
    }
}

优点

  • 实现简单。
  • 类加载时创建实例,线程安全。

缺点

  • 如果单例实例占用资源较大且未使用,会造成资源浪费。
2. 懒汉式(Lazy Initialization)

思想:在第一次需要实例时创建,避免资源浪费,但需要处理多线程问题。

实现方式

public class SingletonLazy {
    private static SingletonLazy instance;

    private SingletonLazy() {
        // 防止实例化的私有构造函数
    }

    public static synchronized SingletonLazy getInstance() {
        if (instance == null) {
            instance = new SingletonLazy();
        }
        return instance;
    }
}

优点

  • 实例在第一次使用时创建,节省资源。

缺点

  • 需要加锁以确保线程安全,性能开销较大。
3. 双重检查锁定(Double-Checked Locking)

思想:结合饿汉式和懒汉式的优点,第一次检查实例是否为 null,避免不必要的同步,提高性能。

实现方式

public class SingletonDCL {
    private static volatile SingletonDCL instance;

    private SingletonDCL() {
        // 防止实例化的私有构造函数
    }

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

优点

  • 提高了懒汉式的性能,减少同步开销。

缺点

  • 代码较为复杂。
4. 静态内部类(Bill Pugh Singleton)

思想:利用类加载机制,只有在使用时才加载内部类,从而实现延迟加载和线程安全。

实现方式

public class SingletonStaticInnerClass {
    private SingletonStaticInnerClass() {
        // 防止实例化的私有构造函数
    }

    private static class SingletonHelper {
        private static final SingletonStaticInnerClass INSTANCE = new SingletonStaticInnerClass();
    }

    public static SingletonStaticInnerClass getInstance() {
        return SingletonHelper.INSTANCE;
    }
}

优点

  • 实现简单。
  • 线程安全。
  • 延迟加载。

缺点

  • 无法进行细粒度控制。
5. 枚举单例(Enum Singleton)

思想:使用 Java 枚举类型的特性,枚举类的实例天生是单例。

实现方式

public enum SingletonEnum {
    INSTANCE;

    public void someMethod() {
        // some method
    }
}

优点

  • 实现最简单。
  • 线程安全。
  • 防止反序列化创建新实例。

缺点

  • 枚举类型不灵活,无法进行细粒度控制。

总结

实现方式优点缺点
饿汉式(Eager Initialization)实现简单,线程安全可能造成资源浪费
懒汉式(Lazy Initialization)实例在第一次使用时创建,节省资源需要加锁以确保线程安全,性能开销较大
双重检查锁定(Double-Checked Locking)提高了懒汉式的性能,减少同步开销代码较为复杂
静态内部类(Bill Pugh Singleton)实现简单,线程安全,延迟加载无法进行细粒度控制
枚举单例(Enum Singleton)实现最简单,线程安全,防止反序列化创建新实例枚举类型不灵活,无法进行细粒度控制

不同的实现方式各有优劣,选择哪种实现方式应根据具体的应用场景和需求来决定。如果需要简单而且线程安全的实现,枚举单例是一个很好的选择。如果需要延迟加载且线程安全,静态内部类和双重检查锁定都是不错的选择。

  • 26
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值