标签:__,name,python,instance,单例,多线程,cls From: https://www.cnblogs.com/dyjnicole/p/17195696.html
# 单例模式处理多线程的问题
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>
'''