一、单例模式到底是什么?
官方定义
单例模式(Singleton Pattern)是一种创建型设计模式,保证:
- 一个类永远只有一个实例
- 提供一个全局访问点获取这个实例
- 禁止外部手动创建新实例
大白话
整个程序运行期间,不管你调用多少次,永远只创建一个对象,大家共用这一个。
核心三要素
- 私有构造函数 :不让别人
new出来 - 静态私有实例:自己保存唯一的那个对象
- 公开静态获取方法:给外部拿对象的入口
二、为什么要用单例?(必须记住的 4 个理由)
- 节约资源
模型、数据库连接、摄像头、日志、配置文件 → 加载一次就够了。 - 避免冲突
多个对象写同一个文件/显存/设备会报错。 - 全局状态统一
配置改一次,全程序生效。 - 控制访问
统一入口,方便管理。
三、单例模式的 2 种核心分类(面试必考)
1. 饿汉式(Eager Initialization)
- 类加载时就创建实例
- 优点:简单、线程安全
- 缺点:不用也占内存
2. 懒汉式(Lazy Initialization)
- 第一次用到时才创建
- 优点:节省资源
- 缺点:需要处理线程安全
四、6 种经典实现方式(从简单到高级)
我用 Python + C++ 都写一遍,你直接复制就能用。
方式1:最简单 Python 单例(new 方法)
最常用、最推荐。
python
class Singleton:
_instance = None # 唯一实例
def __new__(cls, *args, **kwargs):
# 没有实例才创建
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
# 测试
a = Singleton()
b = Singleton()
print(a is b) # True → 同一个对象
方式2:线程安全懒汉式(工业级)
多线程环境必须加锁!
python
import threading
class Singleton:
_instance = None
_lock = threading.Lock() # 锁
def __new__(cls):
with cls._lock: # 加锁保证线程安全
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
方式3:装饰器单例(最优雅)
python
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return getinstance
@singleton
class Model:
pass
m1 = Model()
m2 = Model()
print(m1 is m2) # True
方式4:模块级单例(Python 天然单例)
Python 的 import 机制天生就是单例!
python
# singleton.py
model = YOLO("yolov8.pt")
# main.py
from singleton import model
# 无论 import 多少次,都是同一个对象
这是 Python 最简单、最稳定的单例。
方式5:C++ 饿汉式
cpp
class Singleton {
private:
static Singleton* instance;
Singleton() {} // 私有构造
public:
static Singleton* getInstance() {
return instance;
}
};
Singleton* Singleton::instance = new Singleton();
方式6:C++ 懒汉式(双检锁)
cpp
class Singleton {
private:
static Singleton* instance;
static mutex mtx;
Singleton() {}
public:
static Singleton* getInstance() {
if (instance == nullptr) {
lock_guard<mutex> lock(mtx);
if (instance == nullptr) {
instance = new Singleton();
}
}
return instance;
}
};
五、单例模式的坑点(90%的人踩过)
1. 多线程不安全
懒汉式不加锁 → 会创建多个实例
解决:加锁 / 饿汉式 / 装饰器
2. 序列化/反序列化破坏单例
很少用,但要知道。
3. 反射破坏单例
Java/C# 常见。
4. 单元测试困难
单例全局共享 → 测试互相干扰
解决 :提供 reset() 方法。
5. 内存泄漏
C++ 中需要手动释放。
六、图像 必用场景(超级实用)
1. 深度学习模型加载(最常用)
模型大、加载慢、占显存 → 必须单例
python
class ModelSingleton:
_instance = None
_model = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def get_model(self):
if self._model is None:
self._model = YOLO("yolov8.pt")
return self._model
2. 摄像头/视频流管理
python
class CameraSingleton:
_cap = None
def get_capture(self):
if self._cap is None:
self._cap = cv2.VideoCapture(0)
return self._cap
3. 算法配置管理
python
class ConfigSingleton:
conf = 0.25
iou = 0.45
全程序共用一套参数。
4. GPU 显存管理器
python
class GPUManager:
_instance = None
def allocate(self, size):
# 统一分配显存
pass
5. 日志系统
python
class LoggerSingleton:
def log(self, msg):
print(msg)
七、单例模式总结(一句话记住)
单例 = 一个类永远只有一个对象 + 全局访问 + 节约资源 + 避免冲突