多线程安全的单例模式

方法一:装饰器 

利用装饰器只会执行一次的特性

import time
import threading

def singleton(cls):
    _instance_lock = threading.Lock()

    instances = []# 为什么这里不直接为None,因为内部函数没法访问外部函数的非容器变量
    def getinstance(*args, **kwargs):
        if not instances:
            with _instance_lock:
                if not instances:
                    instances.append(cls(*args, **kwargs))
        return instances[0]
    return getinstance

@singleton
class Foo:
    pass

f1 = Foo()
f2 = Foo()
print(id(f1), id(f2))

  

  

方法二:在做线程中的不使用锁

import time
import threading


class Singleton(object):

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):
            time.sleep(0.1)
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance


class Foo(Singleton):
    def __init__(self):
       pass

obj_list = []
def task(arg):
    obj_list.append(Foo())

for i in range(10):
    t = threading.Thread(target=task, args=(i,))
    t.start()

time.sleep(3)

for obj in obj_list:
    print(id(obj), id(obj))





42769992 42769992
42679096 42679096
42573776 42573776
35682288 35682288
42553072 42553072
42728136 42728136
42728248 42728248
42728080 42728080
42728528 42728528
42764552 42764552

  

方法二:在做线程中的使用锁

import time
import threading


class Singleton(object):
    _instance_lock = threading.Lock()

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, "_instance"):  
            time.sleep(0.1)
            with cls._instance_lock:
                if not hasattr(cls, "_instance"):
                    cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance


class Foo(Singleton):
    def __init__(self):
       pass

obj_list = []
def task(arg):
    obj_list.append(Foo())

for i in range(10):
    t = threading.Thread(target=task, args=(i,))
    t.start()

time.sleep(3)

for obj in obj_list:
    print(id(obj), id(obj))



42573384 42573384
42573384 42573384
42573384 42573384
42573384 42573384
42573384 42573384
42573384 42573384
42573384 42573384
42573384 42573384
42573384 42573384
42573384 42573384

  

原文地址:https://www.cnblogs.com/richiewlq/p/8271646.html