单例模式是一种设计模式,用于确保在应用程序中仅存在一个类的实例,并提供对该实例的全局访问点。
在单例模式中,类的构造函数被限制为仅实例化一次。如果尝试再次实例化该类,则返回现有实例的引用,而不是创建一个新实例。这可以防止多个对象同时修改应用程序的状态,从而提高了应用程序的安全性和可靠性。
单例模式常常被用于管理共享资源或状态,例如缓存、数据库连接、配置文件等。通过限制实例化次数,单例模式可以确保应用程序中只存在一个实例,从而避免资源浪费、状态不一致等问题。
在Python中,可以使用模块、装饰器或元类来实现单例模式。其中,最常见的方法是使用模块。由于在Python中,模块在解释器中只会被导入一次,因此将共享状态或资源存储在模块级别变量中,可以实现单例模式的效果。
装饰器实现单例模式(简单)
import threading
def singleton(cls):
instances = {}
lock = threading.Lock() # 添加锁用于多线程安全
def wrapper(*args, **kwargs):
if cls not in instances:
with lock: # 加锁
if cls not in instances: # 双重检查锁定
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return wrapper
@singleton
class Person:
def __init__(self, name):
print("执行几次?")
self.name = name
def get_name(self):
return self.name
def create_person():
per = Person("小张")
print(per.get_name())
# 创建两个线程同时创建实例
thread1 = threading.Thread(target=create_person)
thread2 = threading.Thread(target=create_person)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
# 输出结果
# 执行几次?
# 小张
# 小张
类中实现单例模式
import threading
from copy import deepcopy
'''
这段代码实现了一个单例模式,确保一个类只有一个实例对象。具体来说,它的实现原理如下:
- 在类的内部定义一个私有的类变量 `_instance` ,初始值为 None。
- 在类的 `__new__` 方法中,如果 `_instance` 已经存在(即不为 None),直接返回 `_instance`。
- 如果 `_instance` 不存在,加锁,再次判断 `_instance` 是否存在,如果不存在,调用 `super().__new__(cls, *args, **kwargs)` 创建一个新的对象,并将其赋值给 `_instance` 变量,然后返回该对象。
- 如果 `_instance` 存在,则直接返回该实例。
- 加锁保证了线程安全,避免了多个线程同时调用时可能会创建多个实例的问题。
这样,我们就可以通过多次实例化一个类,都得到同一个对象的引用。
'''
class Cache:
_instance = None
_lock = threading.RLock()
_init = False
# 单例模式 保证开启单例模式
def __new__(cls, *args, **kwargs):
if cls._instance:
return cls._instance
with cls._lock:
if not cls._instance:
cls._instance = super().__new__(cls, *args, **kwargs)
return cls._instance
def __init__(self):
if self._init:
return
# 加锁 保证安全 保证实例化指向的是同样一个内存 同样一个数据 (只有第一次才会实例化 剩下的直接ruturn 了)
self._init = True # 将 _init 标志为 True
self._frame_time = 0 # 当前帧时戳
self._frame = 0
# 添加缓存
def set_frame(self):
print('frame', self._frame)
self._frame += 1
# 获取缓存
def get_frame(self):
return self._frame
// JS 单例模式
let Singleton = (function() {
let instance;
function createInstance() {
let object = new Object();
return object;
}
return {
getInstance: function() {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
let instance1 = Singleton.getInstance();
let instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true