7. 单例模式
单例模式(Singleton Pattern)是一种常见的软件设计模式,旨在确保一个类只有一个实例,并提供一个全局访问点来获取该实例。在多线程环境下,实现单例模式需要考虑线程安全的问题,以防止多个线程同时创建多个实例。
之前写一个类,每次执行类()时,都会实例化一个类的对象。
python
class Foo:
pass
obj1 = Foo()
obj2 = Foo()
print(obj1 is obj2)需求
需求:每次实例化类的对象时,都是最开始创建的那个对象,不再重复创建新的对象。
实现方式
简易的实现
python
class Singleton:
instance = None
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
# 返回空对象
if cls.instance:
return cls.instance
cls.instance = object.__new__(cls) # 创建空对象
return cls.instance
obj1 = Singleton("对象1")
obj2 = Singleton("对象2")
print(obj1 is obj2) # True线程不安全的实现
python
import threading
import time
class Singleton:
instance = None
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
if cls.instance:
return cls.instance
time.sleep(0.1) # 模拟多线程环境下的竞态条件
cls.instance = object.__new__(cls) # 每个线程都会创建一个空对象
return cls.instance
def task():
obj = Singlenton("单例对象")
print(f"对象ID: {id(obj)}")
for i in range(10):
t = threading.Thread(target=task)
t.start()线程安全的实现
使用多线程加锁,并做双重检查。
python
import threading
import time
class Singleton:
instance = None
lock = threading.RLock()
def __init__(self, name):
self.name = name
def __new__(cls, *args, **kwargs):
if (
cls.instance
): # 再次创建实例的时候,可以快速检查,不需要经过加锁释放锁的步骤。
return cls.instance
with cls.lock: # 加锁,保证同一时刻只有一个线程能执行下面的代码
if cls.instance:
return cls.instance
time.sleep(0.1) # 模拟多线程环境下的竞态条件
cls.instance = object.__new__(cls) # 每个线程都会创建一个空对象
return cls.instance
def task():
obj = Singlenton("单例对象")
print(f"对象ID: {id(obj)}")
for i in range(10):
t = threading.Thread(target=task)
t.start()