• 设计模式之单例


    方式一 通过文件导入实现:

    通过文件导入实现:
    a.py 
        s = 'text'
    b.py
        from a import s as s1
        from a import s as s2  
        print(s1,id(s1))
        print(s1,id(s1))
    #django的admin中的site对象就是通过文件导入的方式来实现的

    方式二 通过类的类方法加线程锁实现:

    通过类的类方法加线程锁实现:
    
    from threading import Thread,Lock
    import time

    class Singleton:
        '''通过类方法实现单例对象的创建'''
    lock = Lock()
    def __init__(self,*args,**kwargs):
    pass
    @classmethod
    def instance(self,*args,**kwargs):
    if not hasattr(self,'_instance'):
    # 线程安全,如果是多线程并发,通过线程锁来实现单例
    with self.lock:
    if not hasattr(self,'_instance'):
    # 先抢到锁的线程会创建一个对象,后续的线程不在创建
    time.sleep(1)
    self._instance = Singleton(*args,**kwargs)
    return self._instance
    def run(item):
    obj = Singleton.instance()
    print(obj,id(obj),'线程%s'%item)
    for i in range(5):
    t = Thread(target=run,args=(i,))
    t.start()
     

    方式三 通过类的静态方法加线程锁实现:

    通过类的静态方法加线程锁实现:
    from threading import Thread,Lock
    import time
    class SingletonS:
    '''通过静态方法实现单例对象的创建'''
    lock = Lock()
    def __init__(self,*args,**kwargs):
    pass
    @staticmethod
    def instance(*args,**kwargs):
    # tornado的IOLoop对象就是基于这样的方式创建的
    if not hasattr(SingletonS,'_instance'):
    with SingletonS.lock:
    if not hasattr(SingletonS,'_instance'):
    time.sleep(1)
    SingletonS._instance = SingletonS(*args,**kwargs)
    return SingletonS._instance
    def run(item):
    obj = SingletonS.instance()
    for i in range(5):
    t = Thread(target=run,args=(i,))
    t.start()

    方式四 通过类的__new__方法加线程锁实现:

    通过类的__new__方法的加线程锁实现:
    
    from threading import Thread,Lock
    import time
    class SingletonN:
    '''通过new方法来实现单例对象的创建'''
    lock = Lock()
    def __init__(self,*args,**kwargs):
    pass
    def __new__(cls, *args, **kwargs):
    if not hasattr(cls,'_instance'):
    with cls.lock:
    if not hasattr(cls,'_instance'):
    time.sleep(1)
    cls._instance = object.__new__(cls)
    #注意object的new方法会调用SingletonN的call方法来创建对象,调用init方法来实现对象的属性赋值
    return cls._instance
    def run(item):
    obj = SingletonN()
    for i in range(5):
    t = Thread(target=run,args=(i,))
    t.start()

     方式五 通过类的__call__方法加线程锁实现:

    通过类的__call__的方法加线程锁实现:
    
    from threading import Thread,Lock
    import time
    class SingletonM:
    '''通过call来实现单例对象的创建'''
    lock = Lock()
    def __init__(self,*args,**kwargs):
    pass
    def __call__(self, *args, **kwargs):
    if not hasattr(SingletonM,'_instance'):
    # 这里的self是每一个线程创建的对象
    # 注意一点的是,反射条件的第一个参数必须是类,而不能是self;因为类是唯一的,而self不是唯一的
    # 这种方式创建的单例,实质上是创建了n+1个对象,只不过最后使用的都是同一个对象(类的_instance属性)
    # n是SingletonM(),1是SingletonM()()
    with self.lock:
    if not hasattr(SingletonM,'_instance'):
    time.sleep(1)
    SingletonM._instance = SingletonM(*args,**kwargs)
    return SingletonM._instance
    def run(item):
    obj = SingletonM()()
    print(obj,id(obj),'线程%s'%item)
    for i in range(5):
    t = Thread(target=run,args=(i,))
    t.start()

     方式六 通过原类及线程锁的方式实现:

    通过原类及线程锁的方式实现
    from threading import Thread,Lock
    import time
    class Meta(type):
        '''通过原类来实现单例的创建'''
        lock = Lock()
        def __call__(self, *args, **kwargs):
            # 注意这里的self是SingletonX类
            if not hasattr(self,'_instance'):
                with self.lock:
                    if not hasattr(self,'_instance'):
                        time.sleep(1)
                        self._instance = type.__call__(self,*args,**kwargs)
            return self._instance
    class SingletonX(metaclass=Meta):
        def __init__(self,*args,**kwargs):
            pass
    def run(item):
    obj = SingletonX()
    print(obj,id(obj),'线程%s'%item)
    for i in range(5):
    t = Thread(target=run,args=(i,))
    t.start()
     
  • 相关阅读:
    bmp和Variant的转换
    获得Variant类型
    移去OleContainer的黑边框
    调整Mic音量
    关闭声道
    检测声卡存在
    控制音量及平衡
    显示媒体时间
    显示Audio CD的音轨时间
    显示AVI文件的桢数
  • 原文地址:https://www.cnblogs.com/aadmina/p/8253219.html
Copyright © 2020-2023  润新知