1.多线程执行单例模式时,容易出bug
import threadingimport timeclass Singleton: instance = None def __init__(self, name): self.name = name def __new__(cls, *args, **kwargs): if cls.instance: return cls.instance time.sleep(0.1) """这里:第一个线程没来得及创建空对象给instance,其他线程发现是空 都着急创建instance空对象,会导致创建出多个空对象 和我们希望出现的单例模式背道而驰,此时应该在这个创建之前加锁 """ cls.instance = object.__new__(cls) return cls.instancedef task(): obj = Singleton('x') print(obj)for i in range(10): t = threading.Thread(target=task) t.start()
2.加锁解决bug
import threadingimport timeclass Singleton: instance = None lock_object = threading.RLock() def __init__(self, name): self.name = name def __new__(cls, *args, **kwargs): with lock_object: if cls.instance: return cls.instance time.sleep(0.1) """这里:第一个线程没来得及创建空对象给instance,其他线程发现是空 都着急创建instance空对象,会导致创建出多个空对象 和我们希望出现的单例模式背道而驰,此时应该在这个创建之前加锁 """ cls.instance = object.__new__(cls) return cls.instancedef task(): obj = Singleton('x') print(obj)for i in range(10): t = threading.Thread(target=task) t.start()
3.加判断提升锁的性能
import threadingimport timeclass Singleton: instance = None lock_object = threading.RLock() def __init__(self, name): self.name = name def __new__(cls, *args, **kwargs): if cls.instance: return cls.instance with lock_object: """这里的if instance必须加上 因为如果不加的话,前面已经判断过是none,当锁释放的时候 会重新创建对象 """ if cls.instance: return cls.instance time.sleep(0.1) """这里:第一个线程没来得及创建空对象给instance,其他线程发现是空 都着急创建instance空对象,会导致创建出多个空对象 和我们希望出现的单例模式背道而驰,此时应该在这个创建之前加锁 """ cls.instance = object.__new__(cls) return cls.instancedef task(): obj = Singleton('x') print(obj)for i in range(10): t = threading.Thread(target=task) t.start()