线程安全的单例模式:from threading import Lock, Thread
classSingletonMeta(type):""" 单例模式的线程安全版本 """
_instances ={}
_lock: Lock = Lock()""" 用锁保证第一次访问单例不会被打断,保证线程同步安全 """def__call__(cls,*args,**kwargs):""" __init__参数的可能变化不会影响返回的实例 """# Now, imagine that the program has just been launched. Since there's no# Singleton instance yet, multiple threads can simultaneously pass the# previous conditional and reach this point almost at the same time. The# first of them will acquire lock and will proceed further, while the# rest will wait here.with cls._lock:# The first thread to acquire the lock, reaches this conditional,# goes inside and creates the Singleton instance. Once it leaves the# lock block, a thread that might have been waiting for the lock# release may then enter this section. But since the Singleton field# is already initialized, the thread won't create a new object.if cls notin cls._instances:
instance =super().__call__(*args,**kwargs)
cls._instances[cls]= instance
return cls._instances[cls]classSingleton(metaclass=SingletonMeta):
value:str=None""" We'll use this property to prove that our Singleton really works. """def__init__(self, value:str)->None:
self.value = value
defsome_business_logic(self):""" Finally, any singleton should define some business logic, which can be executed on its instance. """deftest_singleton(value:str)->None:
singleton = Singleton(value)print(singleton.value)if __name__ =="__main__":# The client code.print("If you see the same value, then singleton was reused (yay!)\n""If you see different values, ""then 2 singletons were created (booo!!)\n\n""RESULT:\n")
process1 = Thread(target=test_singleton, args=("FOO",))
process2 = Thread(target=test_singleton, args=("BAR",))
process1.start()
process2.start()