单例模式是一种常见的设计模式,该模式的主要目的是确保某一个类只有一个实例存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。

比如,服务器的配置信息写在一个文件中online.conf中,客户端通过一个 Config 的类来读取配置文件的内容。如果在程序运行期间,有很多地方都需要使用配置文件的内容,那么每个调用配置文件的地方都会创建 Config的实例,这就导致系统中存在多个Config 的实例对象,在配置文件内容很多的情况下,我们就浪费了大量的内存做了同样的事。事实上,对于Config类我们在程序运行期间时只需要一个实例对象即可,这时单例模式就是最好的选择。

python的模块就是天然的单例模式,这里我们使用修饰器来实现单例模式,以下是代码实现

def Singleton(cls):
    instances = {}

def get_instance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]

return get_instance

代码也很简单,将类传入单例修饰器中,如果该类还未生成实例(instances中不存在该类),那么就生成一个新的实例返回,并记录在instances中。如果已经instances中已经存在该类,那么直接返回实例instances[cls]。

那么这段代码是完美的吗?答案是否定的,这段代码不是线程安全的。要实现线程安全需要配合锁的使用,只有占有锁的线程才能继续访问单例实例,看来我们需要再写一个修饰器来实现线程安全了,以下是完整的代码实现和简单的多线程测试用例。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import threading

def synchronized(func):
    func.__lock__ = threading.Lock()

def synced_func(*args, **kws):
        with func.__lock__:
            return func(*args, **kws)

return synced_func

def Singleton(cls):
    instances = {}

@synchronized
    def get_instance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]

return get_instance

def worker():
    single_test = test()
    print "id----> %s" % id(single_test)

@Singleton
class test():
    a = 1

if __name__ == "__main__":
    task_list = []
    for one in range(30):
        t = threading.Thread(target=worker)
        task_list.append(t)

for one in task_list:
        one.start()

for one in task_list:
        one.join()

转载自 熔遁丶螺旋手里剑  https://www.cnblogs.com/baiyb/p/8506438.html

python 实现线程安全的单例模式相关推荐

  1. python线程安全的单例_详解python实现线程安全的单例模式

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  2. python进阶22再识单例模式

    原创:python进阶22再识单例模式 父子进程内部变量是否可以直接共享,当然不是,需要"特殊加工"下才行. 那么在web开发中的单例模式,是真正的全局唯一的单例么?自然也是否 惭 ...

  3. 搞事情 -- python之线程

    简介 操作系统线程理论 线程概念的引入背景 线程的特点 进程和线程的关系 使用线程的实际场景 用户级线程和内核级线程(了解) 线程和python 理论知识 线程的创建Threading.Thread类 ...

  4. Python:线程之定位与销毁

    背景 开工前我就觉得有什么不太对劲,感觉要背锅.这可不,上班第三天就捅锅了. 我们有个了不起的后台程序,可以动态加载模块,并以线程方式运行,通过这种形式实现插件的功能.而模块更新时候,后台程序自身不会 ...

  5. Python实现线程池

    Python实现线程池 最近在做一些文本处理方面的事情,考虑到程序利用并发性可以提高执行效率(不纠结特殊反例),于是入围的Idea如使用多进程或多线程达到期望的目标,对于进程或线程的创建是有代价的,那 ...

  6. Python基础---线程

    调用方式 python的线程调用有两种方式.一种是直接调用,一种是继承式调用 直接调用 import threading,time#方法一 def run(n):print(n)time.sleep( ...

  7. Android之线程安全的单例模式,Adapter注意事项之引用传值

    线程安全的单例模式 单位模式一般写法如下: public static FestivalLab mInstance; private FestivalLab() { } public static F ...

  8. Python 守护线程

    Python 守护线程 如果你设置一个线程为守护线程,,就表示你在说这个线程是不重要的,在进程退出的时候,不用等待这个线程退出.  如果你的主线程在退出的时候,不用等待那些子线程完成,那就设置这些线程 ...

  9. 孤荷凌寒自学python第三十八天初识python的线程控制

    孤荷凌寒自学python第三十八天初识python的线程控制 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 一.线程 在操作系统中存在着很多的可执行的应用程序,每个应用程序启动后,就可以看着 ...

  10. python关闭线程根据id_python之线程相关操作

    1.线程: 一个进程可以有多个线程,共享一个进程的资源: 2.进程线程的区别: 进程是资源分配的最小单位,线程是程序执行的最小单位 3.python中线程模块threading, 提供的类: Thre ...

最新文章

  1. python3 namedtuple_你不能低估的Python数据结构Namedtuple(二)
  2. linux通过rinetd工具进行端口映射/转发/重定向
  3. sublime3配置pythonIDE
  4. java写 IP十进制转变_java实现ip地址与十进制数相互转换
  5. Android开发之PCM音频流采集| 音频流录制与PCM音频流播放的实现方法
  6. freetextbox java_FreeTextBox-Java架构师必看
  7. 简述静态全局变量的概念 C++
  8. linux ps 程序包,linux ps 详解
  9. abaqus2021+vs2018+intel oneAPI2022关联程序
  10. react-native系列(11)组件篇:Image图片加载和ImageEditor图片剪切
  11. ocm认证年薪多少_年薪 100 万在 IT 行业中,属于什么水平 ?
  12. vue 中v-model原理及应用
  13. 小学生python编程教程-小学生python编程在线教育-小码精灵编程线上教育机构
  14. 学汇率规避风险知识做懂汇率的外贸人
  15. VBA-循环语句之For Each..Next
  16. Mac 安装部署Pcap_DNSProxy
  17. PS动作制作炫酷火焰烟雾人物照片特效
  18. Oracle CBO RBO
  19. matlab 函数pdf怎么用_用smallpdf可以将图片转换成pdf呢?怎么转?
  20. windows 10 ltsc企业版实现C盘系统还原功能

热门文章

  1. 【书评】《IPD 华为研发之道》(著者:刘选鹏)
  2. bootstrap文件上传插件
  3. python 多行注释_python 多行注释
  4. linux中怎么粘贴复制文件路径,如何在Linux中复制文件和目录
  5. python可以用于工业机器人编程与操作_如何实现工业机器人编程抓取
  6. php增删查改数据库,PHP数据库的增删改查
  7. C++静态库与动态库的区别
  8. 静态库和动态库运行时间的区别
  9. 数据恢复原来是可以免费的!
  10. 从编程角度阐述有限元最佳入门方法:以Abaqus 和OpenSees 为例