1 基于类 注意: 加锁,否则多线程模式会报错
import time,threading
class Foo(object):
lock = threading.Lock()
def __init__(self):
time.sleep(1)
@classmethod
def instance(cls,*args,**kwargs):
if not hasattr(cls,'_instance'):
with Foo.lock:
if not hasattr(cls,'_instance'):
obj = cls(*args,**kwargs)
setattr(cls,'_instance',obj)
return cls._instance
def func(arg):
obj = Foo.instance()
print(obj)
for i in range(10):
t = threading.Thread(target=func,args=(i,))
t.start()
2 . 基于new方法,也要加锁,原理同上
import threading,time
class Singleton(object):
lock = threading.Lock()
def __init__(self):
time.sleep(1)
def __new__(cls, *args, **kwargs):
if not hasattr(cls,'_instance'):
with Singleton.lock:
if not hasattr(cls,'_instance'):
Singleton._instance = object.__new__(cls,*args,**kwargs)
return Singleton._instance
def task(args):
obj = Singleton()
print(obj)
for i in range(10):
t = threading.Thread(target=task,args=(i,))
t.start()
- 基于metaclass 加锁,原理同上
import threading
class SingletonType(type):
lock = threading.Lock()
def __call__(cls, *args, **kwargs):
if not hasattr(cls,'_instance'):
with SingletonType.lock:
if not hasattr(cls,'_instance'):
cls._instance = super(SingletonType, cls).__call__(*args,**kwargs)
return cls._instance
class Foo(metaclass=SingletonType):
def __init__(self):
pass
obj = Foo()
obj2 = Foo()
总结:单利模式存在的目的是保证当前内存中仅存在单个实例,避免内存浪费,在Django admin的源码中,就用到了单例模式!!!