python线程安全单例_python 单例模式

python的单例模式实现:

重写类的__new__方法即可

参照官网的解释:

3.4.1. Basic customization

object.__new__(cls[, ...])

Called to create a new instance of class cls. __new__() is a static method (special-cased so you need not declare it as such) that takes the class of which an instance was requested as its first argument. The remaining arguments are those passed to the object constructor expression (the call to the class). The return value of __new__() should be the new object instance (usually an instance of cls).

Typical implementations create a new instance of the class by invoking the superclass’s __new__() method using super(currentclass, cls).__new__(cls[, ...]) with appropriate arguments and then modifying the newly-created instance as necessary before returning it.

If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[,...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().

If __new__() does not return an instance of cls, then the new instance’s __init__() method will not be invoked.

__new__() is intended mainly to allow subclasses of immutable types (like int, str, or tuple) to customize instance creation. It is also commonly overridden in custom metaclasses in order to customize class creation.

class db(object):

__instance = None

def __init__(self):

self.host = '10.0.0.1'

self.port = '3306'

self.user = 'root'

self.password = '123456'

def __new__(cls,*args,**kwargs):

if cls.__instance is  None:

cls.__instance = super(db,cls).__new__(cls,*args,**kwargs)

return cls.__instance

In [2]: a=db()

In [3]: b=db()

In [4]: c=db()

In [5]: a

Out[5]: <__main__.db>

In [6]: b

Out[6]: <__main__.db>

In [7]: c

Out[7]: <__main__.db>

In [8]: a.host

Out[8]: '10.0.0.1'

In [9]: b.port

Out[9]: '3306'

In [10]: c.user

Out[10]: 'root'

In [11]: c.password='uiso'

In [12]: b.password

Out[12]: 'uiso'

In [13]: a.password

Out[13]: 'uiso'

可以看到, 初始化&实例化所使用的都是同一个对象,用来长连接的保持会非常好. 但是这种写法不是线程安全的。

在多线程下,我们需要导入使用threading的特性,使用锁来保证线程安全

Lock = threading.Lock()

将__new__方法重写为:def __new__(cls, *args, **kwargs):

if not cls.__instance:

try:

Lock.acquire()

if not cls.__instance:

cls.__instance = super(db, cls).__new__(cls, *args, **kwargs)

finally:

Lock.release()

return cls.__instance

double check来保证线程的安全。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值