Python单例模式的代码实现和原理

Python单例设计模式的代码实现

python 复制代码
import threading
import time


class Singleton(object):  
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)
            cls._instance = orig.__new__(cls, *args, **kw)
        return cls._instance



class Bus(Singleton):
    lock = threading.RLock()

    def sendData(self, data):
        self.lock.acquire()
        time.sleep(3)
        print("Sending Signal Data...", data)
        self.lock.release()



class VisitEntity(threading.Thread):
    my_bus = ""
    name = ""

    def getName(self):
        return self.name

    def setName(self, name):
        self.name = name

    def run(self):
        self.my_bus = Bus()
        self.my_bus.sendData(self.name)


if __name__ == "__main__":
    for i in range(3):
        print("Entity %d begin to run..." % i)
        my_entity = VisitEntity()
        my_entity.setName("Entity_"+str(i))
        my_entity.start()

这段代码实现并演示了Python中的单例模式,下面详细解释其代码实现和原理:

代码实现

单例类 Singleton 的定义:

python 复制代码
class Singleton(object):  
    def __new__(cls, *args, **kw):
        if not hasattr(cls, '_instance'):
            orig = super(Singleton, cls)
            cls._instance = orig.__new__(cls, *args, **kw)
        return cls._instance
  • new 是Python类的一个特殊方法,用于创建并返回一个实例化对象。在单例模式里,它首先检查类属性 _instance 是否存在。如果不存在,就通过调用父类的 new 方法来创建一个新实例,并将其赋值给 _instance ;如果已经存在,直接返回这个已有的实例。
    Bus 类:
python 复制代码
class Bus(Singleton):
    lock = threading.RLock()

    def sendData(self, data):
        self.lock.acquire()
        time.sleep(3)
        print("Sending Signal Data...", data)
        self.lock.release()
  • Bus 类继承自 Singleton 类,也就继承了单例的特性。它定义了一个线程锁 lock ,用于在多线程环境下同步访问资源, sendData 方法用于发送数据,通过获取锁、模拟耗时操作、释放锁来保证线程安全。
    VisitEntity 线程类:
python 复制代码
class VisitEntity(threading.Thread):
    my_bus = ""
    name = ""

    def getName(self):
        return self.name

    def setName(self, name):
        self.name = name

    def run(self):
        self.my_bus = Bus()
        self.my_bus.sendData(self.name)
  • VisitEntity 继承自 threading.Thread ,重写了 run 方法。在 run 方法中,它获取 Bus 类的单例实例,并调用其 sendData 方法发送数据,模拟多线程访问单例对象的场景。
    主程序部分:
python 复制代码
if __name__ == "__main__":
    for i in range(3):
        print("Entity %d begin to run..." % i)
        my_entity = VisitEntity()
        my_entity.setName("Entity_"+str(i))
        my_entity.start()
  • 在主程序中,创建了3个 VisitEntity 线程,为每个线程设置名字后启动它们,观察多线程环境下单例对象的运行情况。

原理

  • 单例模式的核心目标:确保一个类只有一个实例,并提供一个全局访问点。在这段代码里,利用 new 方法的特性,类第一次实例化时创建对象,后续实例化请求都返回这个已创建好的对象,以此保证整个程序生命周期内特定类的实例唯一性。
  • 线程安全性:由于多线程环境下,多个线程可能同时尝试创建实例,代码引入了线程锁( RLock )。在 Bus 类的 sendData 方法中,当线程访问共享资源(这里模拟发送数据的操作)时,先获取锁,操作完成后释放锁,防止数据竞争和不一致问题,保证单例模式在并发场景下正常工作。运行这段代码,会发现虽然有多个线程尝试访问 Bus 实例,但它们操作的是同一个实例,并且按顺序依次执行 sendData 方法。
相关推荐
Ray Liang13 分钟前
用六边形架构与整洁架构对比是伪命题?
java·python·c#·架构设计
AI攻城狮28 分钟前
如何给 AI Agent 做"断舍离":OpenClaw Session 自动清理实践
python
千寻girling31 分钟前
一份不可多得的 《 Python 》语言教程
人工智能·后端·python
七月丶4 小时前
别再手动凑 PR 了:这个 AI Skill 会按仓库习惯自动建分支、拆提交、提 PR
人工智能·设计模式·程序员
刀法如飞4 小时前
从程序员到架构师:6大编程范式全解析与实践对比
设计模式·系统架构·编程范式
AI攻城狮4 小时前
用 Playwright 实现博客一键发布到稀土掘金
python·自动化运维
曲幽4 小时前
FastAPI分布式系统实战:拆解分布式系统中常见问题及解决方案
redis·python·fastapi·web·httpx·lock·asyncio
九狼4 小时前
Flutter + Riverpod +MVI 架构下的现代状态管理
设计模式
孟健19 小时前
Karpathy 用 200 行纯 Python 从零实现 GPT:代码逐行解析
python