方式一 通过文件导入实现:
通过文件导入实现: a.py s = 'text' b.py from a import s as s1 from a import s as s2 print(s1,id(s1)) print(s1,id(s1))
#django的admin中的site对象就是通过文件导入的方式来实现的
方式二 通过类的类方法加线程锁实现:
通过类的类方法加线程锁实现:
from threading import Thread,Lock
import time
class Singleton:
'''通过类方法实现单例对象的创建'''
lock = Lock()
def __init__(self,*args,**kwargs):
pass
@classmethod
def instance(self,*args,**kwargs):
if not hasattr(self,'_instance'):
# 线程安全,如果是多线程并发,通过线程锁来实现单例
with self.lock:
if not hasattr(self,'_instance'):
# 先抢到锁的线程会创建一个对象,后续的线程不在创建
time.sleep(1)
self._instance = Singleton(*args,**kwargs)
return self._instance
def run(item):
obj = Singleton.instance()
print(obj,id(obj),'线程%s'%item)
for i in range(5):
t = Thread(target=run,args=(i,))
t.start()
方式三 通过类的静态方法加线程锁实现:
通过类的静态方法加线程锁实现:
from threading import Thread,Lock
import time
class SingletonS:
'''通过静态方法实现单例对象的创建'''
lock = Lock()
def __init__(self,*args,**kwargs):
pass
@staticmethod
def instance(*args,**kwargs):
# tornado的IOLoop对象就是基于这样的方式创建的
if not hasattr(SingletonS,'_instance'):
with SingletonS.lock:
if not hasattr(SingletonS,'_instance'):
time.sleep(1)
SingletonS._instance = SingletonS(*args,**kwargs)
return SingletonS._instance
def run(item):
obj = SingletonS.instance()
for i in range(5):
t = Thread(target=run,args=(i,))
t.start()
方式四 通过类的__new__方法加线程锁实现:
通过类的__new__方法的加线程锁实现:
from threading import Thread,Lock
import time
class SingletonN:
'''通过new方法来实现单例对象的创建'''
lock = Lock()
def __init__(self,*args,**kwargs):
pass
def __new__(cls, *args, **kwargs):
if not hasattr(cls,'_instance'):
with cls.lock:
if not hasattr(cls,'_instance'):
time.sleep(1)
cls._instance = object.__new__(cls)
#注意object的new方法会调用SingletonN的call方法来创建对象,调用init方法来实现对象的属性赋值
return cls._instance
def run(item):
obj = SingletonN()
for i in range(5):
t = Thread(target=run,args=(i,))
t.start()
方式五 通过类的__call__方法加线程锁实现:
通过类的__call__的方法加线程锁实现:
from threading import Thread,Lock
import time
class SingletonM:
'''通过call来实现单例对象的创建'''
lock = Lock()
def __init__(self,*args,**kwargs):
pass
def __call__(self, *args, **kwargs):
if not hasattr(SingletonM,'_instance'):
# 这里的self是每一个线程创建的对象
# 注意一点的是,反射条件的第一个参数必须是类,而不能是self;因为类是唯一的,而self不是唯一的
# 这种方式创建的单例,实质上是创建了n+1个对象,只不过最后使用的都是同一个对象(类的_instance属性)
# n是SingletonM(),1是SingletonM()()
with self.lock:
if not hasattr(SingletonM,'_instance'):
time.sleep(1)
SingletonM._instance = SingletonM(*args,**kwargs)
return SingletonM._instance
def run(item):
obj = SingletonM()()
print(obj,id(obj),'线程%s'%item)
for i in range(5):
t = Thread(target=run,args=(i,))
t.start()
方式六 通过原类及线程锁的方式实现:
通过原类及线程锁的方式实现
from threading import Thread,Lock
import time
class Meta(type): '''通过原类来实现单例的创建''' lock = Lock() def __call__(self, *args, **kwargs): # 注意这里的self是SingletonX类 if not hasattr(self,'_instance'): with self.lock: if not hasattr(self,'_instance'): time.sleep(1) self._instance = type.__call__(self,*args,**kwargs) return self._instance class SingletonX(metaclass=Meta): def __init__(self,*args,**kwargs): pass
def run(item):
obj = SingletonX()
print(obj,id(obj),'线程%s'%item)
for i in range(5):
t = Thread(target=run,args=(i,))
t.start()