博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
类的多线程下实现单例类
阅读量:4963 次
发布时间:2019-06-12

本文共 2211 字,大约阅读时间需要 7 分钟。

 

 

这两天在看自己之前写的代码,所以正好把用过的东西整理一下,单例模式,在日常的代码工作中也是经常被用到,

所以这里把之前用过的不同方式实现的单例方式整理一下

 

装饰器的方式

这种方式也是工作中经常用的一种,用起来也比较方便,代码实现如下

复制代码
def Singleton(cls):    _instance = {}    def _singleton(*args, **kwargs):        if cls not in _instance:            _instance[cls] = cls(*args, **kwargs)        return _instance[cls] return _singleton
复制代码

如果我们工作的一个类需要用单例就通过类似下面的方式实现即可:

@Singletonclass A(object):    def __init__(self, x):        self.x = x

我个人还是挺喜欢这种方式的

类的方式实现

这里其实有一些问题就需要注意了,先看一下可能出现的错误代码

复制代码
class Member(object):    @classmethod    def instance(cls, *args, **kwargs):        if not hasattr(Member, "_instance"):            Member._instance = Member(*args, **kwargs)        return Member._instance
复制代码

乍一看这个类好像已经实现了单例,但是这里有一个潜在的问题,就是如果是多线程的情况,这样写就会有问题了,尤其是在当前类的初始化对象里有一些耗时操作时候

例如下面代码:

复制代码
#! /usr/bin/env python3# .-*- coding:utf-8 .-*-import timeimport threadingimport randomclass Member(object):        def __init__(self):        time.sleep(random.randint(1,3)) @classmethod def instance(cls, *args, **kwargs): if not hasattr(Member, "_instance"): Member._instance = Member(*args, **kwargs) return Member._instance def task(arg): obj = Member.instance() print(obj) for i in range(5): t = threading.Thread(target=task, args=[i,]) t.start()
复制代码

这段代码的执行结果会出现实例化了多个对象,导致你写的单例就没起到作用

当然自然而然我们会想起加锁,通过锁来控制,所以我们将上面代码进行更改:

复制代码
#! /usr/bin/env python3# .-*- coding:utf-8 .-*-import timeimport threadingimport randomclass Member(object):    _instance_lock = threading.Lock()    def __init__(self): i = random.randint(1, 3) print(i) time.sleep(i) @classmethod def instance(cls, *args, **kwargs): with Member._instance_lock: if not hasattr(Member, "_instance"): Member._instance = Member(*args, **kwargs) return Member._instance def task(): obj = Member.instance() print(obj) for i in range(5): threading.Thread(target=task,).start()
复制代码

但是上面的代码还有一个问题,就是当我们已经实例化过之后每次调用instance都会去请求锁,所以这点并不好,所以我们将这部分代码再次更改:

复制代码
@classmethod    def instance(cls, *args, **kwargs):        if not hasattr(Member, "_instance"):            with Member._instance_lock:                if not hasattr(Member, "_instance"):                    Member._instance = Member(*args, **kwargs)        return Member._instance
复制代码

 

这样就很好的实现一个可以多线程使用的单例

 
 

转载于:https://www.cnblogs.com/laogao123/p/10140533.html

你可能感兴趣的文章
Linux系统中ElasticSearch搜索引擎安装配置Head插件
查看>>
int*-------int
查看>>
【2015 ICPC亚洲区域赛长春站 G】Dancing Stars on Me(几何+暴力)
查看>>
11-2犀牛读书笔记
查看>>
Python发送带附件的邮件
查看>>
golang 反向代理
查看>>
1001. A+B Format (20)
查看>>
Spring Boot初识(4)- Spring Boot整合JWT
查看>>
二叉树的镜像
查看>>
Android ExpandableGridView的实现
查看>>
HTML连载12-体验CSS
查看>>
装箱和拆箱
查看>>
iOS开发日记9-终端命令
查看>>
Git学习一
查看>>
《软件工程》 第二周 作业
查看>>
HTTP协议
查看>>
【iOS开发】多屏尺的自动适配 AutoLayout (纯代码方式)
查看>>
mysql 数据增删改查基本语句
查看>>
20155322 2017-2018-1《信息安全系统设计》实验二:固件程序设计
查看>>
安装supset遇到的问题
查看>>