python线程安全的单例模式
⼀、默认情况
实例化⼏次,就有⼏个实例。
1.1 单线程
import time
class Singleton:
def__init__(self):
time.sleep(1)
print('init successfully')
if __name__ =='__main__':
obj1 = Singleton()
obj2 = Singleton()
obj3 = Singleton()
print(id(obj1))
print(id(obj2))
print(id(obj3))
每过1秒,完成⼀个实例化,输出⼀个“init successfully”,程序总共需要3秒运⾏完成。⽣成了3个实例。
init successfully
init successfully
init successfully
4467431760
4467497552
4467517264
1.2 多线程
import time
import threading
class Singleton:
def__init__(self,num):
time.sleep(1)
print('init successfully',num)
def task(num):
obj = Singleton(num)
print(id(obj))
if __name__ =='__main__':
for i in range(3):
t = threading.Thread(target=task,args=(i,))
t.start()
开三个⼦线程并⾏执⾏,总共需要1秒左右。和单线程⼀样,也是⽣成3个实例
init successfully 1
init successfully 0
4311585552
4310474832
init successfully 2
4311585872
⼆、普通单例
2.1 单线程
import time
class Singleton:
_instance =None
def__new__(cls,*args,**kwargs):
if cls._instance is None:
print('new successfully')
time.sleep(1)
cls._instance =super().__new__(cls) return cls._instance
def__init__(self):
print('init successfully')
if __name__ =='__main__':python单例模式
obj1 = Singleton()
obj2 = Singleton()
obj3 = Singleton()
print(id(obj1))
print(id(obj2))
print(id(obj3))
单线程中⽣成了1个实例,实现了单例模式
new successfullyinit successfully
init successfully
init successfully
4415949264
4415949264
4415949264
2.2 多线程
import time
import threading
class Singleton:
_instance =None
def__new__(cls,*args,**kwargs):
if cls._instance is None:
print('new successfully')
time.sleep(1)
cls._instance =super().__new__(cls) return cls._instance
def__init__(self):
print('init successfully')
def task():
obj = Singleton()
print(id(obj))
if __name__ =='__main__':
for i in range(3):
t = threading.Thread(target=task)
t.start()
多线程中仍然⽣成了3个实例
new successfullynew successfully new successfully
init successfully
4346787280
init successfully
4346787344
init successfully
4345682448
三、线程安全的单例
3.1 单线程
import time
import threading
class Singleton:
_instance =None
_lock = threading.Lock()
def__new__(cls,*args,**kwargs):
with cls._lock:
if cls._instance is None:
print('new successfully')
time.sleep(1)
cls._instance =super().__new__(cls) return cls._instance
def__init__(self):
print('init successfully')
if __name__ =='__main__':
obj1 = Singleton()
obj2 = Singleton()
obj3 = Singleton()
print(id(obj1))
print(id(obj2))
print(id(obj3))
单线程中⽣成了1个实例
new successfully
init successfully
init successfully
init successfully
4567881744
4567881744
4567881744
3.2 多线程
_lock = threading.Lock()
def__new__(cls,*args,**kwargs):
with cls._lock:
if cls._instance is None:
print('new successfully')
time.sleep(1)
cls._instance =super().__new__(cls)
return cls._instance
def__init__(self):
print('init successfully')
def task():
obj = Singleton()
print(id(obj))
if __name__ =='__main__':
for i in range(3):
t = threading.Thread(target=task)
t.start()
多线程中也⽣成了1个实例。
new successfully
init successfully
4357391696
init successfully
4357391696
init successfully
4357391696
四、调⽤⼀次__init__
上⾯【三】中虽然只⽣成了⼀个实例,但是__init__⽅法却仍然调⽤了三次,下⾯实现只调⽤⼀次__init__⽅法。单线程
_lock = threading.Lock()
_init_flag =False
def__new__(cls,*args,**kwargs):
with cls._lock:
if cls._instance is None:
print('new successfully')
time.sleep(1)
cls._instance =super().__new__(cls) return cls._instance
def__init__(self):
if not Singleton._init_flag:
print('init successfully')
Singleton._init_flag =True
if __name__ =='__main__':
obj1 = Singleton()
obj2 = Singleton()
obj3 = Singleton()
print(id(obj1))
print(id(obj2))
print(id(obj3))
单线程实现了只调⽤了⼀次__init__
new successfully
init successfully
4321122256
4321122256
4321122256
多线程

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。