之前的学习,遗漏了一个关于单例模式在多线程场景下的是否存在线程安全的问题,这里补充一下如果保障再多线程环境中创建单例的时候,线程安全的问题。(但是如果是不需要再多线程环境下创建的话,其实是不需要的)
多线程环境下,创建单例对象的时候总是会去判断实例对象是否已经创建,如果存在多个线程同时创建了对象的时候,就超出预期的单例模式,所以在多线程的环境时,创建单例对象的时候需要加锁。
# coding:utf-8
import threading
# 锁方法装饰器
def synchronized(func):
# 方法锁
func.__lock__ = threading.Lock()
def lock_func(*args, **kwargs):
with func.__lock__:
return func(*args, **kwargs)
return lock_func
class Singleton():
"""
单例模式
"""
instance = None
# 给当前的方法进行上锁
@synchronized
def __new__(cls, *args, **kwargs):
if cls.instance is None:
# cls.instance = object.__new__(cls, *args, **kwargs)
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls.instance
def worker():
e = Singleton()
print(id(e))
if __name__ == "__main__":
# test()
task = []
for one in range(1000):
t = threading.Thread(target=worker)
task.append(t)
# 启动多线程
for one in task:
one.start()
# 等到所有的线程执行完毕
for one in task:
one.join()
import threading
class Singleton:
_instance = None
_lock = threading.Lock()
def __new__(cls, *args, **kwargs):
if not cls._instance:
with cls._lock:
if not cls._instance: # Double-checked locking
cls._instance = super(Singleton, cls).__new__(cls, *args, **kwargs)
return cls._instance
def __init__(self):
self.blog = "xiaorui.cc"
def go(self):
pass
def worker():
e = Singleton()
print(id(e))
if __name__ == "__main__":
# test()
task = []
for one in range(1000):
t = threading.Thread(target=worker)
task.append(t)
# 启动多线程
for one in task:
one.start()
# 等到所有的线程执行完毕
for one in task:
one.join()
❝简书:https://www.jianshu.com/u/d6960089b087
掘金:https://juejin.cn/user/2963939079225608
小钟同学 | 文 【原创】| QQ:308711822
❝
1:本文相关描述主要是个人的认知和见解,如有不当之处,还望各位大佬指正。 2:关于文章内容,有部分内容参考自互联网,如有链接会声明标注;如没有及时标注备注的链接的,如有侵权请联系,我会立即删除处理哟。
原文作者:程序员小钟同学;如有侵权,请联系管理员删除。