zoukankan      html  css  js  c++  java
  • 设计模式之单例

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

    通过文件导入实现:
    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()
     
  • 相关阅读:
    POJ 1703 Find them, Catch them
    POJ 2236 Wireless Network
    POJ 2010 Moo University
    POJ 2184 Cow Exhibition
    POJ 3280 Cheapest Palindrome
    POJ 3009 Curling 2.0
    POJ 3669 Meteor Shower
    POJ 2718 Smallest Difference
    POJ 3187 Backward Digit Sums
    POJ 3050 Hopscotch
  • 原文地址:https://www.cnblogs.com/aadmina/p/8253219.html
Copyright © 2011-2022 走看看