python 单例模式

#coding=utf-8
import threading, time

#整个try的这一段其实就是定义了一个装饰器 make_synchronized
try:
    from synchronize import make_synchronized
except ImportError:
    def make_synchronized(func):
        func.__lock__ = threading.Lock()

        def synced_func(*args, **kws):
            #with 会自动给threading.Lock 获取锁和释放锁(资源)
            with func.__lock__:
                return func(*args, **kws)  #锁定期间, 其他线程获取不到资源
        return synced_func

class Singleton(object):
    instance = None

    @make_synchronized
    def __new__(cls, *args, **kwargs):
        #__new___ 本身用来初始化实例, 如果check 到内存中有初始化的实例则直接返回内存地址
        #如果check到没有实例化的实例则调用父类的__new__重新进行初始化实例, 之所以说调用父类的__new__
        #是因为我们实际上是重载了object的__new__
        #__new__的返回就是__init__中的self值
        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 __init__(self):
        #time.sleep(1)
        self.blog = "brownz"

    def go(self):
        #定义全局变量, 所有线程均可调用
        global num
        for i in xrange(1000000):
            num += 1
        print "go num is:", num, time.time()

def worker():
    e = Singleton()
    print e.blog
    print id(e)
    e.go()

def test():
    e1 = Singleton()
    e2 = Singleton()
    e1.blog = 123
    print e1.blog
    print e2.blog
    print id(e1)
    print id(e2)

if __name__ == "__main__":
    test()
    task = []
    num = 0
    for i in range(3):
        t = threading.Thread(target=worker())
        task.append(t)
        t.start()

    for threadlist in task:
        threadlist.join()

[out]:

:Project-workspacepython_testThread>python singleton.py
123
123
40365264
40365264
brownz
40365264
go num is: 1000000 1536060468.22
brownz
40365264
go num is: 2000000 1536060468.3
brownz
40365264
go num is: 3000000 1536060468.38

windows下面看不出上不上锁的区别, 自行理解多线程的上锁机制吧

原文地址:https://www.cnblogs.com/brownz/p/9588030.html