python单例模式处理多线程问题


# 单例模式处理多线程的问题
import threading
import time


class Single:
instance = None

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

def __new__(cls, *args, **kwargs):
if not cls.instance:
time.sleep(0.1)
cls.instance = object.__new__(cls)
return cls.instance


def dotask():
obj = Single("test")
print(obj)


for i in range(10):
t = threading.Thread(target=dotask)
t.start()
# 在使用多线程的情况下。输出id不同,说明此单例模式是存在问题的:
'''

<__main__.Single object at 0x000002C16CEA67C0><__main__.Single object at 0x000002C16CEA6850>
<__main__.Single object at 0x000002C16CEA1DC0>
<__main__.Single object at 0x000002C16CEA1640><__main__.Single object at 0x000002C16CEA1F10>
<__main__.Single object at 0x000002C16CEA18B0>
<__main__.Single object at 0x000002C16CEA1400>
<__main__.Single object at 0x000002C16CEA1670>

<__main__.Single object at 0x000002C16CEA1640>

<__main__.Single object at 0x000002C16CE9CF10>
'''
# 要解决多线程的单例模式,需要添加锁来处理
import threading
import time



class Single2:
instance = None
lock = threading.RLock()

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

def __new__(cls, *args, **kwargs):
with cls.lock:
if not cls.instance:
time.sleep(0.1)
cls.instance = object.__new__(cls)
return cls.instance


def dotask():
obj = Single2("test")
print(obj)


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

# 此时输出就完全一致了:
'''
<__main__.Single2 object at 0x00000204B9A30C70><__main__.Single2 object at 0x00000204B9A30C70>

<__main__.Single2 object at 0x00000204B9A30C70>
<__main__.Single2 object at 0x00000204B9A30C70>
<__main__.Single2 object at 0x00000204B9A30C70>
<__main__.Single2 object at 0x00000204B9A30C70>
<__main__.Single2 object at 0x00000204B9A30C70>
<__main__.Single2 object at 0x00000204B9A30C70><__main__.Single2 object at 0x00000204B9A30C70><__main__.Single2 object at 0x00000204B9A30C70>

'''
posted @ 2023-03-08 18:23  dyjnicole  阅读(121)  评论(0编辑  收藏  举报