详解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 中的with关键字使用详解
Sep 11 Python
解决python读取几千万行的大表内存问题
Jun 26 Python
Django框架多表查询实例分析
Jul 04 Python
利用pandas进行大文件计数处理的方法
Jul 25 Python
python常用库之NumPy和sklearn入门
Jul 11 Python
Django为窗体加上防机器人的验证码功能过程解析
Aug 14 Python
python中的itertools的使用详解
Jan 13 Python
浅谈Python3实现两个矩形的交并比(IoU)
Jan 18 Python
Django 允许局域网中的机器访问你的主机操作
May 13 Python
pytorch 计算ConvTranspose1d输出特征大小方式
Jun 23 Python
利用python绘制中国地图(含省界、河流等)
Sep 21 Python
python 爬取腾讯视频评论的实现步骤
Feb 18 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
JAVA/JSP学习系列之七
2006/10/09 PHP
PHP数组和explode函数示例总结
2015/05/08 PHP
PHP如何使用Memcached
2016/04/05 PHP
php获取用户真实IP和防刷机制的实例代码
2018/11/28 PHP
jQuery对象与DOM对象之间的转换方法
2010/04/15 Javascript
基于jquery的监控数据是否发生改变
2011/04/11 Javascript
JQuery UI的拖拽功能实现方法小结
2012/03/14 Javascript
javascript 构造函数强制调用经验总结
2012/12/02 Javascript
JQuery的AJAX实现文件下载的小例子
2013/05/15 Javascript
深入理解JavaScript系列(48):对象创建模式(下篇)
2015/03/04 Javascript
jQuery实现table中的tr上下移动并保持序号不变的实例代码
2016/07/11 Javascript
javascript 实现文本使用省略号替代(超出固定高度的情况)
2017/02/21 Javascript
微信小程序如何使用globalData的方法
2019/06/06 Javascript
解决mui框架中switch开关通过js控制开或者关状态时小圆点不动的问题
2019/09/03 Javascript
vue props对象validator自定义函数实例
2019/11/13 Javascript
小程序实现简单语音聊天的示例代码
2020/07/24 Javascript
vue+iview实现分页及查询功能
2020/11/17 Vue.js
Python连接mysql数据库的正确姿势
2016/02/03 Python
Python模拟简单电梯调度算法示例
2018/08/20 Python
python学习开发mock接口
2019/04/28 Python
Python 解决OPEN读文件报错 ,路径以及r的问题
2019/12/19 Python
opencv python在视屏上截图功能的实现
2020/03/05 Python
Python 去除字符串中指定字符串
2020/03/05 Python
django实现将修改好的新模型写入数据库
2020/03/31 Python
简单介绍CSS3中Media Query的使用
2015/07/07 HTML / CSS
世界排名第一的万圣节服装店:Spirit Halloween
2018/10/16 全球购物
英格兰足协官方商店:England Store
2019/07/12 全球购物
单位消防安全制度
2014/01/12 职场文书
DIY手工制作经营店创业计划书
2014/02/01 职场文书
员工合理化建议书
2014/05/19 职场文书
2014年国庆标语
2014/06/30 职场文书
节能环保演讲稿
2014/08/28 职场文书
老龙头导游词
2015/02/11 职场文书
护士医德考评自我评价
2015/03/03 职场文书
小学生节水倡议书
2015/04/29 职场文书
python3 sqlite3限制条件查询的操作
2021/04/07 Python