单例模式:保证只有一个实例的设计
发布时间: 2024-01-02 02:52:57 阅读量: 11 订阅数: 15
# 1. 引言
## 1.1 什么是单例模式?
单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来访问该实例。
## 1.2 单例模式的作用和意义
单例模式的主要作用是控制对象的创建和访问权限,能够在系统中确保只有一个实例存在,从而提供一个全局的、独一无二的对象访问点。
单例模式的意义在于可以节省系统资源,避免不必要的对象创建和销毁操作,提高系统性能和效率。同时,它也可以确保某些场景下只能有一个实例存在,如线程池、数据库连接池等。
## 1.3 单例模式在实际项目中的应用
单例模式在实际项目中有广泛的应用,特别是对于需要频繁访问某个对象的场景,通过单例模式可以避免重复创建和销毁对象的开销。
在以下场景中,单例模式都可以被使用:
- 日志管理器
- 数据库连接池
- 线程池
- 系统配置对象
- 对象池
- 缓存管理器
单例模式非常适用于多线程环境下的对象访问控制,它能够解决多线程竞争资源的问题,确保只有一个实例存在。
在接下来的章节中,我们将介绍几种经典的单例模式的实现方式,并探讨其优缺点以及在实际项目中的应用场景。
# 2. 经典单例模式的实现
### 2.1 饿汉式单例模式
饿汉式单例模式是指在类加载的时候就创建实例,即在程序启动或者单例模式类被加载的时候,单例对象就已经被创建。这种方式实现简单,线程安全,但可能会浪费内存空间。
```java
public class HungrySingleton {
private static final HungrySingleton instance = new HungrySingleton();
private HungrySingleton() {
}
public static HungrySingleton getInstance() {
return instance;
}
}
```
**场景应用:** 当需要保证在整个程序周期内只有一个实例存在,并且实例创建较为简单时,可以考虑使用饿汉式单例模式。
**代码总结:** 饿汉式单例模式通过类加载的方式保证了线程安全,但在程序启动时就创建实例可能会占用不必要的内存空间。
**结果说明:** 使用饿汉式单例模式可以保证在程序运行期间只有一个实例存在,且线程安全,但可能会带来额外的内存开销。
### 2.2 懒汉式单例模式
懒汉式单例模式是指在第一次调用获取实例的方法时才会去创建实例,这种方式实现简单,但需要考虑线程安全性。
```java
public class LazySingleton {
private static LazySingleton instance;
private LazySingleton() {
}
public static synchronized LazySingleton getInstance() {
if (instance == null) {
instance = new LazySingleton();
}
return instance;
}
}
```
**场景应用:** 当单例对象的创建操作较为耗时,或者在程序中实际使用时才需要创建实例时,可以考虑使用懒汉式单例模式。
**代码总结:** 懒汉式单例模式在需要时才创建实例的方式下,可以节约内存空间,但需要考虑线程安全问题。
**结果说明:** 使用懒汉式单例模式可以延迟对象的创建,在一定程度上节约内存空间,但需要考虑线程安全性。
### 2.3 双重检查锁实现单例模式
双重检查锁实现单例模式是在懒汉式基础上进行优化,通过双重检查来减少同步的开销,提高性能。
```java
public class DoubleCheckedSingleton {
private volatile static DoubleCheckedSingleton instance;
private DoubleCheckedSingleton() {
}
public static DoubleCheckedSingleton getInstance() {
if (instance == null) {
synchronized (DoubleCheckedSingleton.class) {
if (instance == null) {
instance = new DoubleCheckedSingleton();
}
}
}
return instance;
}
}
```
**场景应用:** 当需要保证线程安全的同时又提高性能时,可以考虑使用双重检查锁实现单例模式。
**代码总结:** 双重检查锁实现单例模式在保证线程安全的同时减少了同步的开销,提高了性能。
**结果说明:** 使用双重检查锁实现单例模式可以在保证线程安全的前提下提高性能,但需要注意volatile关键字的使用。
### 2.4 静态内部类实现单例模式
静态内部类实现单例模式是利用了类加载的特性,内部类在外部类加载时并不会立即加载,可实现延迟加载。
```java
public class StaticInnerClassSingleton {
private StaticInnerClassSingleton() {
}
private static class SingletonHolder {
private static final StaticInnerClassSingleton INSTANCE = new StaticInnerClassSingleton();
}
public static StaticInnerClassSingleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
```
**场景应用:** 当需要实现延迟加载且能保证线程安全时,可以考虑使用静态内部类实现单例模式。
**代码总结:** 静态内部类实现单例模式通过类加载机制保证了线程安全及延迟加载。
**结果说明:** 使用静态内部类实现单例模式可以保证在程序运行时只有一个实例存在,且在需要时才会被加载,且能保证线程安全。
# 3. 单例模式的优缺点
### 3.1 优点:保证只有一个实例
单例模式的主要优点是可以确保一个类只有一个
0
0