并发编程(3)扩展—单例模式

之前写一个类,每次执行 类() 都会实例化一个类的对象。

class Foo:
    pass

obj1 = Foo()

obj2 = Foo()
print(obj1,obj2)

以后开发会遇到单例模式,每次实例化类的对象时,都是最开始创建的那个对象,不再重复创建对象。

  • 简单的实现单例模式

    class Singleton:
        instance = None
    
        def __init__(self, name):
            self.name = name
            
        def __new__(cls, *args, **kwargs):
            # 返回空对象
            if cls.instance:
                return cls.instance
            cls.instance = object.__new__(cls)
            return cls.instance
    
    obj1 = Singleton('alex')
    obj2 = Singleton('SB')
    
    print(obj1,obj2)
    
  • 多线程执行单例模式,有BUG

    import threading
    import time
    
    
    class 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)
            cls.instance = object.__new__(cls)
            return cls.instance
    
    
    def task():
        obj = Singleton('x')
        print(obj)
    
    
    for i in range(10):
        t = threading.Thread(target=task)
        t.start()
    
    
  • 加锁解决BUG

    import threading
    import time
    class Singleton:
        instance = None
        lock = threading.RLock()
    
        def __init__(self, name):
            self.name = name
            
        def __new__(cls, *args, **kwargs):
            with cls.lock:
                if cls.instance:
                    return cls.instance
                time.sleep(0.1)
                cls.instance = object.__new__(cls)
            return cls.instance
    
    def task():
        obj = Singleton('x')
        print(obj)
    
    for i in range(10):
        t = threading.Thread(target=task)
        t.start()
    
  • 加判断,提升性能

    import threading
    import time
    class Singleton:
        instance = None
        lock = threading.RLock()
    
        def __init__(self, name):
            self.name = name
            
        def __new__(cls, *args, **kwargs):
    
            if cls.instance:
                return cls.instance
            with cls.lock:
                if cls.instance:
                    return cls.instance
                time.sleep(0.1)
                cls.instance = object.__new__(cls)
            return cls.instance
    
    def task():
        obj = Singleton('x')
        print(obj)
    
    for i in range(10):
        t = threading.Thread(target=task)
        t.start()
    
    # 执行1000行代码
    
    data = Singleton('asdfasdf')
    print(data)
    
posted @ 2021-11-15 23:33  下个ID见  阅读(8)  评论(0)    收藏  举报