从本篇文章开始,我们就进入到了单例模式,关于单例模式里的分支模式会在后续的文章中一一讲解
什么是单例模式
单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供了全局访问点。单例模式确保在系统中,该类只有唯一的一个实例存在,并提供了一个访问该实例的全局点,以便全局访问。单例模式常用于管理共享资源,例如线程池、缓存、日志对象等等,这些资源需要在整个应用程序中共享和访问。如果每次需要访问这些资源时都要创建一个新对象,不仅会影响程序性能,还会占用过多的系统资源。 单例模式可以通过以下几种方式来实现:
- 懒汉式单例:在需要时才创建单例对象,但是在多线程环境下需要使用同步来保证只有一个实例。
- 饿汉式单例:在类加载时就创建单例对象,但是可能会浪费资源。
- 双重检验锁单例:结合了懒汉式和饿汉式的优点,同时也需要使用同步来保证线程安全。
- 静态内部类单例:通过内部类的特性实现延迟加载和线程安全。
- 枚举单例:枚举类型保证了只有一个枚举常量,因此可以直接作为单例来使用,而且线程安全。
单例模式可以保证全局只有一个实例,避免了不必要的资源浪费和对象创建的额外开销。同时,单例模式也是一种常见的设计模式,开发人员应该在实际开发中合理应用。
如何实现懒汉式单例模式
懒汉式单例的实现步骤如下:
- 将构造函数设为私有,防止外部直接创建实例。
- 在类中定义一个私有的静态变量用于保存单例实例,初始值为 null。
- 提供一个公有的静态方法,返回类的唯一实例。在该方法中,如果实例为 null,就创建一个新的实例,并将其赋值给静态变量,否则直接返回现有实例。
Java实现
代码语言:javascript复制public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
// 私有构造函数
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
在上面的代码中,getInstance() 方法是获取懒汉式单例实例的方法,使用 synchronized 关键字保证了线程安全。当第一个线程调用 getInstance() 方法时,会创建一个新的实例并将其赋值给 instance 变量,随后其他线程调用 getInstance() 方法时,直接返回已经创建的实例。这种实现方式简单易懂,但是在多线程环境下会存在性能问题。
C#实现
代码语言:javascript复制public class LazySingleton {
private static LazySingleton instance = null;
private static readonly object padlock = new object();
private LazySingleton() {
// 私有构造函数
}
public static LazySingleton GetInstance() {
lock (padlock) {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
}
在上面的代码中,GetInstance() 方法是获取懒汉式单例实例的方法,使用 lock 关键字保证了线程安全。当第一个线程调用 GetInstance() 方法时,会创建一个新的实例并将其赋值给 instance 变量,随后其他线程调用 GetInstance() 方法时,直接返回已经创建的实例。这种实现方式简单易懂,和Java实现一样,在多线程环境下会存在性能问题。
总结
懒汉式单例模式是一种常用的创建型设计模式,它能够确保一个类只有一个实例,并提供了一个全局访问点。这种模式的核心思想是在需要的时候才去创建实例,从而避免了不必要的资源浪费。懒汉式单例模式的实现相对简单,只需要将构造函数设为私有,定义一个私有的静态变量保存单例实例,提供一个公有的静态方法返回类的唯一实例即可。但是需要注意的是,在多线程环境下,需要加锁保证线程安全。懒汉式单例模式的缺点是性能问题,由于每次获取实例都需要进行线程同步,所以在高并发环境下可能会出现性能瓶颈。