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


Posted in Python onMarch 05, 2018

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

比如,服务器的配置信息写在一个文件中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()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现将16进制字符串转化为ascii字符的方法分析
Jul 21 Python
Python实现识别手写数字大纲
Jan 29 Python
使用Python从零开始撸一个区块链
Mar 14 Python
python使用正则表达式来获取文件名的前缀方法
Oct 21 Python
Windows系统下PhantomJS的安装和基本用法
Oct 21 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
Dec 05 Python
Python调用服务接口的实例
Jan 03 Python
对Python强大的可变参数传递机制详解
Jun 13 Python
matlab中imadjust函数的作用及应用举例
Feb 27 Python
细说NumPy数组的四种乘法的使用
Dec 18 Python
linux中nohup和后台运行进程查看及终止
Jun 24 Python
Python 如何利用ffmpeg 处理视频素材
Nov 27 Python
分析python动态规划的递归、非递归实现
Mar 04 #Python
python3.x上post发送json数据
Mar 04 #Python
python数据封装json格式数据
Mar 04 #Python
Python爬虫实例扒取2345天气预报
Mar 04 #Python
Python爬虫设置代理IP的方法(爬虫技巧)
Mar 04 #Python
浅析python实现scrapy定时执行爬虫
Mar 04 #Python
Python使用Scrapy爬虫框架全站爬取图片并保存本地的实现代码
Mar 04 #Python
You might like
如何使用PHP往windows中添加用户
2006/12/06 PHP
php ci框架中加载css和js文件失败的原因及解决方法
2014/07/29 PHP
10个实用的PHP正则表达式汇总
2014/10/23 PHP
PHP 枚举类型的管理与设计知识点总结
2020/02/13 PHP
javascript编程起步(第二课)
2007/01/10 Javascript
不使用中间变量,交换int型的 a, b两个变量的值。
2010/10/29 Javascript
javascript管中窥豹 形参与实参浅析
2011/12/17 Javascript
JavaScript高级程序设计 阅读笔记(十四) js继承机制的实现
2012/08/14 Javascript
通过隐藏iframe实现文件下载的js方法介绍
2014/02/26 Javascript
深入分析js的冒泡事件
2014/12/05 Javascript
JS实现的5级联动Select下拉选择框实例
2015/08/17 Javascript
jquery实现网页的页面平滑滚动效果代码
2015/11/02 Javascript
JS中Json数据的处理和解析JSON数据的方法详解
2016/06/29 Javascript
jquery移除了live()、die(),新版事件绑定on()、off()的方法
2016/10/26 Javascript
jquery与js实现全选功能的区别
2017/06/11 jQuery
python函数返回多个值的示例方法
2013/12/04 Python
python通过scapy获取局域网所有主机mac地址示例
2014/05/04 Python
约瑟夫问题的Python和C++求解方法
2015/08/20 Python
python数据结构之链表详解
2017/09/12 Python
解决Mac安装scrapy失败的问题
2018/06/13 Python
Scrapy框架爬取西刺代理网免费高匿代理的实现代码
2019/02/22 Python
Pyqt5实现英文学习词典
2019/06/24 Python
pytorch 数据处理:定义自己的数据集合实例
2019/12/31 Python
如何基于pandas读取csv后合并两个股票
2020/09/25 Python
python爬虫泛滥的解决方法详解
2020/11/25 Python
Nike比利时官网:Nike.com (BE)
2019/02/07 全球购物
试述DBMS的主要功能
2016/11/13 面试题
缓刑人员的思想汇报
2014/01/11 职场文书
市场营销管理制度
2014/01/29 职场文书
见习报告怎么写
2014/10/31 职场文书
离婚协议书怎么写的
2014/12/14 职场文书
学校艾滋病宣传活动总结
2015/05/09 职场文书
法律意见书范本
2015/06/04 职场文书
JavaGUI模仿QQ聊天功能完整版
2021/07/04 Java/Android
python编程简单几行代码实现视频转换Gif示例
2021/10/05 Python
vue使用watch监听属性变化
2022/04/30 Vue.js