You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
4.9 KiB

"""
单例模式 (Singleton Pattern)
意图:确保一个类只有一个实例,并提供一个全局访问点。
应用场景:
- 资源管理器(如数据库连接池、线程池)
- 配置管理器
- 日志记录器
- 全局计数器
本实现提供了三种常见的单例模式实现方式:
1. 懒汉式 (延迟初始化)
2. 饿汉式 (立即初始化)
3. 线程安全的懒汉式 (使用双重检查锁定)
"""
class LazySingleton:
"""懒汉式单例 - 延迟初始化,非线程安全"""
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super(LazySingleton, cls).__new__(cls)
# 初始化代码
cls._instance.data = "Lazy Singleton Data"
return cls._instance
def do_something(self):
"""演示单例的功能方法"""
return f"{self.__class__.__name__} is doing something with {self.data}"
class EagerSingleton:
"""饿汉式单例 - 立即初始化,线程安全"""
_instance = None
# 在类加载时就创建实例
def __new__(cls):
if cls._instance is None:
cls._instance = super(EagerSingleton, cls).__new__(cls)
# 初始化代码
cls._instance.data = "Eager Singleton Data"
return cls._instance
def do_something(self):
"""演示单例的功能方法"""
return f"{self.__class__.__name__} is doing something with {self.data}"
import threading
class ThreadSafeSingleton:
"""线程安全的懒汉式单例 - 使用双重检查锁定模式"""
_instance = None
_lock = threading.RLock() # 使用可重入锁
def __new__(cls):
# 第一次检查,避免不必要的锁
if cls._instance is None:
# 获取锁
with cls._lock:
# 第二次检查,确保在等待锁的过程中没有其他线程创建实例
if cls._instance is None:
cls._instance = super(ThreadSafeSingleton, cls).__new__(cls)
# 初始化代码
cls._instance.data = "Thread Safe Singleton Data"
return cls._instance
def do_something(self):
"""演示单例的功能方法"""
return f"{self.__class__.__name__} is doing something with {self.data}"
class Singleton:
"""使用元类实现的单例模式"""
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
def __init__(self, data=None):
# 仅在第一次初始化时设置属性
if not hasattr(self, 'initialized'):
self.data = data or "Default Singleton Data"
self.initialized = True
def do_something(self):
"""演示单例的功能方法"""
return f"{self.__class__.__name__} is doing something with {self.data}"
def test_thread_safety():
"""测试线程安全性"""
instances = []
def create_instance():
instances.append(ThreadSafeSingleton())
# 创建多个线程同时实例化
threads = []
for _ in range(10):
thread = threading.Thread(target=create_instance)
threads.append(thread)
thread.start()
# 等待所有线程完成
for thread in threads:
thread.join()
# 验证所有实例都是同一个对象
first_id = id(instances[0])
for instance in instances[1:]:
assert id(instance) == first_id, "线程安全测试失败:创建了多个实例"
print("线程安全测试通过:所有线程创建的是同一个实例")
def main():
"""演示各种单例实现"""
print("=== 单例模式演示 ===")
# 测试懒汉式单例
print("\n1. 懒汉式单例测试:")
s1 = LazySingleton()
s2 = LazySingleton()
print(f"s1 id: {id(s1)}, s2 id: {id(s2)}")
print(f"s1 == s2: {s1 is s2}")
print(s1.do_something())
# 测试饿汉式单例
print("\n2. 饿汉式单例测试:")
s3 = EagerSingleton()
s4 = EagerSingleton()
print(f"s3 id: {id(s3)}, s4 id: {id(s4)}")
print(f"s3 == s4: {s3 is s4}")
print(s3.do_something())
# 测试线程安全的懒汉式单例
print("\n3. 线程安全单例测试:")
test_thread_safety()
s5 = ThreadSafeSingleton()
s6 = ThreadSafeSingleton()
print(f"s5 id: {id(s5)}, s6 id: {id(s6)}")
print(f"s5 == s6: {s5 is s6}")
print(s5.do_something())
# 测试使用元类的单例
print("\n4. 元类单例测试:")
s7 = Singleton("Custom Data")
s8 = Singleton("This should not change") # 第二次初始化不会改变数据
print(f"s7 id: {id(s7)}, s8 id: {id(s8)}")
print(f"s7 == s8: {s7 is s8}")
print(f"s7.data: {s7.data}") # 应该是 "Custom Data"
print(s7.do_something())
if __name__ == "__main__":
main()