python 单例模式

#  记录两种常用的单例模式
# 第一种
复制代码
import threading
import time


class Singleton(object):
_instance = None

def __init__(self):
time.sleep(3)

@classmethod
def instance(cls, *args, **kwargs):
if not cls._instance:
cls._instance = cls(*args, **kwargs)
return cls._instance


# 在多线程时会有问题
s1 = Singleton.instance()
s2 = Singleton.instance()
print(s1)
print(s2)
复制代码
#  在多线程时,如果在__init__方法中存在IO操作,导致在对象创建过程中出现线程切换,单例模式就会失败。例如,在__init__中加入sleep,再使用多线程创建对象。
def create():
s = Singleton.instance()
print(s)


for i in range(10):
t = threading.Thread(target=create)
t.start()

#    输出结果如下:

复制代码
<__main__.Singleton object at 0x0000022C12E65208>
<__main__.Singleton object at 0x0000022C12E65048>
<__main__.Singleton object at 0x0000022C12E653C8> <__main__.Singleton object at 0x0000022C12E653C8> <__main__.Singleton object at 0x0000022C12E653C8> <__main__.Singleton object at 0x0000022C12E653C8> <__main__.Singleton object at 0x0000022C12E653C8> <__main__.Singleton object at 0x0000022C12E5AE48> <__main__.Singleton object at 0x0000022C12E5AE48>
<__main__.Singleton object at 0x0000022C12E5A978>
复制代码

#    解决办法加锁:

复制代码
class Singleton(object):
    _instance = None
    _instance_lock = threading.Lock()

    def __init__(self):
        time.sleep(3)

    @classmethod
    def instance(cls, *args, **kwargs):
        cls._instance_lock.acquire()
        if not cls._instance:
            cls._instance = cls(*args, **kwargs)
        cls._instance_lock.release()
        return cls._instance
复制代码

#    第二种:

#    在创建对象时,先执行__new__方法,因此在__new__方法中实现单例模式,这种方法的好处在于创建对象时和普通创建对象相同

复制代码
class Singleton(object):
_instance = None

def __init__(self):
time.sleep(2)

def __new__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance


s1 = Singleton()
s2 = Singleton()
print(s1)
print(s2)
复制代码

#    本来以为在使用多线程测试时,会出现和第一种方法相同的问题,但是,测试来看没有发现这个问题,所以也就没有加锁了。

 

 

 

 










posted @   守望人间  阅读(219)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示