详解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之用Python计算
Sep 12 Python
python映射列表实例分析
Jan 26 Python
Python爬虫爬取美剧网站的实现代码
Sep 03 Python
Python用threading实现多线程详解
Feb 03 Python
在cmder下安装ipython以及环境的搭建
Oct 19 Python
python实践项目之监控当前联网状态详情
May 23 Python
python实现字典嵌套列表取值
Dec 16 Python
解决Tensorflow 内存泄露问题
Feb 05 Python
Python实现动态循环输出文字功能
May 07 Python
python+playwright微软自动化工具的使用
Feb 02 Python
python第三方网页解析器 lxml 扩展库与 xpath 的使用方法
Apr 06 Python
Python基础之tkinter图形化界面学习
Apr 29 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
第八节--访问方式
2006/11/16 PHP
PHP 抓取新浪读书频道的小说并生成txt电子书的代码
2009/12/18 PHP
PHP 导出Excel示例分享
2014/08/18 PHP
php获取从html表单传递数组的方法
2015/03/20 PHP
windows server 2008/2012安装php iis7 mysql环境搭建教程
2016/06/30 PHP
学习thinkphp5.0验证类使用方法
2017/11/16 PHP
PHP $O00OO0=urldecode & eval 解密,记一次商业源码的去后门
2020/09/13 PHP
jquery 回车事件实现代码
2011/08/23 Javascript
Array 重排序方法和操作方法的简单实例
2014/01/24 Javascript
jquery序列化form表单使用ajax提交后处理返回的json数据
2014/03/03 Javascript
jQuery判断div随滚动条滚动到一定位置后停止
2014/04/02 Javascript
简介JavaScript中search()方法的使用
2015/06/06 Javascript
jQuery实现鼠标滑向当前图片高亮显示并且其它图片变灰的方法
2015/07/27 Javascript
javascript自定义滚动条实现代码
2020/04/20 Javascript
JavaScript+Java实现HTML页面转为PDF文件保存的方法
2016/05/30 Javascript
Angular4自制一个市县二级联动组件示例
2017/11/21 Javascript
Element Input组件分析小结
2018/10/11 Javascript
微信小程序 生成携带参数的二维码
2019/10/23 Javascript
js中复选框的取值及赋值示例详解
2020/10/18 Javascript
如何运行Python程序的方法
2013/04/21 Python
python中使用OpenCV进行人脸检测的例子
2014/04/18 Python
解决Python 遍历字典时删除元素报异常的问题
2016/09/11 Python
python实现上传下载文件功能
2020/11/19 Python
详解Python下载图片并保存本地的两种方式
2019/05/15 Python
python递归法解决棋盘分割问题
2019/07/17 Python
django云端留言板实例详解
2019/07/22 Python
python实现杨辉三角的几种方法代码实例
2021/03/02 Python
可持续木材、生态和铝制太阳镜:Proof Eyewear
2019/07/24 全球购物
信息技术课后反思
2014/04/27 职场文书
2015年小学开学寄语
2015/02/27 职场文书
2015年度学校卫生工作总结
2015/05/12 职场文书
大学生暑期实践报告
2015/07/13 职场文书
Nginx域名转发https访问的实现
2021/03/31 Servers
python操作xlsx格式文件并读取
2021/06/02 Python
新手初学Java List 接口
2021/07/07 Java/Android
排查并解决MySQL生产库内存使用率高的报警
2022/04/11 MySQL