for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start()
程序执行↓
1 2 3 4 5 6 7 8 9 10
<__main__.sing_leton object at 0x000001F80176FAC8> <__main__.sing_leton object at 0x000001F80176FAC8> <__main__.sing_leton object at 0x000001F80176FAC8> <__main__.sing_leton object at 0x000001F80176FAC8> <__main__.sing_leton object at 0x000001F80176FAC8> <__main__.sing_leton object at 0x000001F80176FAC8> <__main__.sing_leton object at 0x000001F80176FAC8> <__main__.sing_leton object at 0x000001F80176FAC8> <__main__.sing_leton object at 0x000001F80176FAC8> <__main__.sing_leton object at 0x000001F80176FAC8>
看起来好像也没有什么毛病,但是真的没有毛病吗?,我们来修改一下相关的代码
1 2 3 4 5 6 7 8 9 10
class sing_leton: def __init__(self): import time time.sleep(1)
@classmethod def get_instance(cls,*args,**kwargs): if not hasattr(sing_leton,"_instance"): sing_leton._instance = sing_leton(*args,**kwargs) return sing_leton._instance
执行得到了这样的结果。
1 2 3 4 5
<__main__.sing_leton object at 0x000001ED128C4438><__main__.sing_leton object at 0x000001ED128C4F60> <__main__.sing_leton object at 0x000001ED128C4898><__main__.sing_leton object at 0x000001ED128C45C0> <__main__.sing_leton object at 0x000001ED128C4F28><__main__.sing_leton object at 0x000001ED128C46D8> <__main__.sing_leton object at 0x000001ED128C4588><__main__.sing_leton object at 0x000001ED1290EC50> <__main__.sing_leton object at 0x000001ED128C4550><__main__.sing_leton object at 0x000001ED1290EA58>
那么问题出现了,创建的单例模式,却无法支持多线程的访问。那有什么解决方案呢。
解决方法: 加锁啊!加锁的部分串行,不加锁部分并行。保证了安全。
1 2 3 4 5 6 7 8 9 10 11 12
class sing_leton: _instance_lock = threading.Lock() def __init__(self): import time time.sleep(2)
@classmethod def get_instance(cls,*args,**kwargs): with sing_leton._instance_lock: if not hasattr(sing_leton,"_instance"): sing_leton._instance = sing_leton(*args,**kwargs) return sing_leton._instance
执行如下:
1 2 3 4 5 6 7 8 9 10
<__main__.sing_leton object at 0x000001ED128A9470> <__main__.sing_leton object at 0x000001ED128A9470> <__main__.sing_leton object at 0x000001ED128A9470> <__main__.sing_leton object at 0x000001ED128A9470> <__main__.sing_leton object at 0x000001ED128A9470> <__main__.sing_leton object at 0x000001ED128A9470> <__main__.sing_leton object at 0x000001ED128A9470> <__main__.sing_leton object at 0x000001ED128A9470> <__main__.sing_leton object at 0x000001ED128A9470> <__main__.sing_leton object at 0x000001ED128A9470>
class sing_leton: _instance_lock = threading.Lock() def __init__(self): import time time.sleep(2)
@classmethod def get_instance(cls,*args,**kwargs): if not hasattr(sing_leton,"_instance"): with sing_leton._instance_lock: if not hasattr(sing_leton,"_instance"): sing_leton._instance = sing_leton(*args,**kwargs) return sing_leton._instance