详解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中base64加密解密方法实例分析
May 16 Python
用Python的Flask框架结合MySQL写一个内存监控程序
Nov 07 Python
简单总结Python中序列与字典的相同和不同之处
Jan 19 Python
Python环境搭建之OpenCV的步骤方法
Oct 20 Python
pyqt5之将textBrowser的内容写入txt文档的方法
Jun 21 Python
用python画一只可爱的皮卡丘实例
Nov 21 Python
Python调用shell命令常用方法(4种)
May 11 Python
python实现数据结构中双向循环链表操作的示例
Oct 09 Python
python爬虫爬取图片的简单代码
Jan 18 Python
Python list去重且保持原顺序不变的方法
Apr 03 Python
从np.random.normal()到正态分布的拟合操作
Jun 02 Python
Python人工智能之混合高斯模型运动目标检测详解分析
Nov 07 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
一个改进的UBB类
2006/10/09 PHP
php查看session内容的函数
2008/08/27 PHP
PHP原生模板引擎 最简单的模板引擎
2012/04/25 PHP
PHP设计模式之迭代器模式的深入解析
2013/06/13 PHP
兼容ie和firefox js关闭代码
2008/12/11 Javascript
JavaScript获取GridView选择的行内容
2009/04/14 Javascript
表单类各种类型(文本框)失去焦点效果jquery代码
2013/04/26 Javascript
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
2013/11/03 Javascript
toggle()隐藏问题的解决方法
2014/02/17 Javascript
基于jQuery Circlr插件实现产品图片360度旋转
2015/09/20 Javascript
基于replaceChild制作简单的吞噬特效
2015/09/21 Javascript
js实现新浪微博首页效果
2015/10/16 Javascript
jQuery实现简单的点赞效果
2020/05/29 Javascript
js实现select二级联动下拉菜单
2020/04/17 Javascript
AngularJS实践之使用NgModelController进行数据绑定
2016/10/08 Javascript
微信小程序 less文件编译成wxss文件实现办法
2016/12/05 Javascript
JavaScript实现打地鼠小游戏
2020/04/23 Javascript
浅谈vue自定义全局组件并通过全局方法 Vue.use() 使用该组件
2017/12/07 Javascript
JS检索下拉列表框中被选项目的索引号(selectedIndex)
2019/12/17 Javascript
解决VUEX的mapState/...mapState等取值问题
2020/07/24 Javascript
vue 页面回退mounted函数不执行的解决方案
2020/07/26 Javascript
python调用shell的方法
2013/11/20 Python
Python2/3中urllib库的一些常见用法
2017/12/19 Python
Python 批量读取文件中指定字符的实现
2020/03/06 Python
Python实现http接口自动化测试的示例代码
2020/10/09 Python
Python爬虫+Tkinter制作一个翻译软件的示例
2021/02/20 Python
Python使用paramiko连接远程服务器执行Shell命令的实现
2021/03/04 Python
贝尔帐篷精品店:Bell Tent Boutique
2019/06/12 全球购物
护理职业生涯规划书
2014/01/24 职场文书
金融系毕业生自荐书
2014/07/08 职场文书
宣传稿格式范文
2015/07/23 职场文书
交通安全主题班会
2015/08/12 职场文书
2016年第29个世界无烟日宣传活动总结
2016/04/06 职场文书
宪法宣传标语100条
2019/10/15 职场文书
python 经纬度求两点距离、三点面积操作
2021/06/03 Python
python机器学习实现oneR算法(以鸢尾data为例)
2022/03/03 Python