Skip to content

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()

构建时间:11/21/2025, 1:28:39 PM | 本博客内容均为自己学习,如内容涉及侵权,请联系邮箱:pangzl0215@163.com